Webpack 4 - копировать структуру каталога - PullRequest
0 голосов
/ 13 ноября 2018

На данный момент у меня есть структура Webpack 4 & Handlebars

src/
├── assets/
│   ├── css/
│   ├── fonts/
│   ├── img/
│   ├── js/
│   ├── scss/
│   └── vendor/
├── helpers/
│   ├── repeat.js
│   └── compare.js
├── partials/
│   ├── header.hbs
│   └── footer.hbs
├── index.hbs
├── subpage1.hbs
└── subpage2.hbs

и он прекрасно компилируется в

dest/
├── assets/
│   ├── css/
│   ├── fonts/
│   ├── img/
│   ├── js/
│   ├── scss/
│   └── vendor/
├── index.html
├── subpage1.html
└── subpage2.html

Я согласен с этим, но клиент хочет, чтобы вместо subpage1.html, subpage2.html ... вложенных папок /subpage1/ и т. Д., Содержащих другой index.html, они могли иметь хорошие URL-адреса без htaccess и, как они сказал, что это более читабельно: - /

Вопрос в том, как я могу копировать подкаталоги, а также обрабатывать файлы рулей в них:

src/
├── assets/
│   ├── css/
│   ├── fonts/
│   ├── img/
│   ├── js/
│   ├── scss/
│   └── vendor/
├── helpers/
│   ├── repeat.js
│   └── compare.js
├── partials/
│   ├── header.hbs
│   └── footer.hbs
├── subpage1/
│   └── index.hbs
├── subpage2/
│   └── index.hbs
└── index.hbs

Если мне удастся выполнить этот шаг, возникнет еще одна проблема - обработать относительные пути и сделать их абсолютным путем к изображениям, css, bundle.js

Это общий конфиг моего веб-пакета:

const path = require('path');
const webpack = require('webpack');
const handlebars = require('handlebars');
const utils = require('handlebars-utils');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const vars = require('./variables.js');
const glob = require('glob');

const generateHTMLPlugins = () =>
    glob.sync('./src/*.{html,hbs}').map(item => {
        return new HtmlWebpackPlugin({
            filename: path.parse(item).name + '.html', 
            template: item
        });
    });

module.exports = {
    context: vars.relativePath,
    entry: [
        vars.src.relativePath + vars.src.assetsPath + 'js/scripts.js'
    ],
    output: {
        path: vars.dist.relativePath,
        filename: vars.dist.assetsPath + 'js/bundle.js'
    },
    plugins: [
        new webpack.LoaderOptionsPlugin({
            options: {
              handlebarsLoader: {}
            }
        }),
        new CopyWebpackPlugin([ // images folder
            {
                from: vars.src.relativePath + vars.src.assetsPath + 'img',
                to: vars.dist.relativePath + vars.dist.assetsPath + 'img'
            }
        ]),
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQuery: 'jquery',
            'window.jQuery': 'jquery',
            Popper: ['popper.js', 'default']
        }),
        ...generateHTMLPlugins()
    ],
    module: {
        rules: [
            {
                test: /\.js?$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env']
                    }
                }
            },
            {
                test: /\.hbs$/,
                loader: 'handlebars-loader',
                query: {
                    helperDirs: [vars.src.relativePath + 'helpers'],
                    partialDirs: [vars.src.relativePath + 'partials'],
                    precompileOptions: {
                        knownHelpersOnly: false,
                    },
                }
            },
            { // Compile and merge sass + css
                test: /\.s?css/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader,
                        options: {
                            sourceMap: (this.mode == 'production') ? false : true
                        }
                    },
                    {
                        loader: 'css-loader',
                        options: {
                            sourceMap: (this.mode == 'production') ? false : true
                        }
                    },
                    {
                        loader: 'postcss-loader',
                        options: {
                            plugins: [
                                require('autoprefixer'),
                                require('cssnano')({
                                    discardComments: { removeAll: true }
                                }),
                            ],
                            sourceMap: (this.mode == 'production') ? false : true
                        }
                    },
                    {
                        loader: 'sass-loader',
                        options: {
                            sourceMap: (this.mode == 'production') ? false : true
                        }
                    }
                ]
            },
            { // Fonts
                test: /\.woff($|\?)|\.woff2($|\?)|\.ttf($|\?)|\.eot($|\?)|\.svg($|\?)/,
                exclude: /img\//,
                use: {
                    loader: "file-loader",
                    options: {
                        name: '[name].[ext]',
                        publicPath: '../fonts/',
                        outputPath: vars.dist.assetsPath + 'fonts/',
                    }
                },
            },
            { // Context images
                test: /\.(jpe?g|png|gif|svg)/,
                exclude: /font/,
                use: {
                    loader: "file-loader",
                    options: {
                        name: '[name].[ext]',
                        publicPath: '../img/',
                        outputPath: vars.dist.assetsPath + 'img/'
                    }
                }
            },
        ]
    }
};

Переменные веб-пакета:

const path = require('path');
const relativePath = path.resolve(__dirname, '../');
const argv = require('yargs').argv;
const theme = (argv.name === undefined) ? 'default' : argv.name

module.exports = {
    relativePath: relativePath,
    dist: {
        path: 'dist/',
        relativePath: relativePath + '/dist/', 
        assetsPath: 'assets/'
        // assetsPath: 'assets/' + theme + '/'
    },
    src: {
        path: 'src/',
        relativePath: relativePath + '/src/', 
        assetsPath: 'assets/'
        // assetsPath: 'assets/' + theme + '/'
    }    
}

и производственный конфиг

const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const AggressiveMergingPlugin = require('webpack/lib/optimize/AggressiveMergingPlugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const vars = require('./variables.js');

module.exports = merge(common, {
    output: {
        path: vars.dist.relativePath,
        filename: vars.dist.assetsPath + 'js/bundle.js'
    },
    mode: 'production',
    plugins: [
        new MiniCssExtractPlugin({
            filename: vars.dist.assetsPath + 'css/style.min.css',
            allChunks: true,
        }),
        new UglifyJsPlugin(), //minify everything
        new AggressiveMergingPlugin(), //Merge chunks
        new CleanWebpackPlugin([vars.dist.path],{
            root: vars.relativePath
        })
    ]
})

1 Ответ

0 голосов
/ 14 ноября 2018

Итак .. Я нашел решение .. может быть, не элегантное, но оно работает.Это для рекурсивных hbs to html, за исключением партиалов dir:

glob.sync('./src/**/*.{html,hbs}', {"ignore": ['./src/partials/*']} ).map(item => {
    return new HtmlWebpackPlugin({
        // filename: path.parse(item).name + '.html', 
        filename: path.resolve(__dirname, '../') + path.parse(item).dir.replace('./src', '/dist') + '/' + path.parse(item).name + '.html', 
        template: item
    });
});

и окончательной установки абсолютного пути для public

output: {
    path: vars.dist.relativePath,
    publicPath: '/',
    filename: vars.dist.assetsPath + 'js/bundle.js'
},
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...