@codemafia
Самоотвод

Как правильно настроить webpack4 для работы с pug?

Приветствую. Хочу полностью отказаться от gulp в пользу webpack, но при настройке не понял, почему webpack-dev-server не видит сгенерированные html файлы?
Структура проекта
/
    node_modules
    public_html
    source
        legacy
            files
            js
            pug
            scss
            svg            
        new
            ...
    webpack.config.js

package.json/scripts
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "clean": "del-cli public_html\\assets public_html\\fav* public_html\\*.html -f",
    "prebuild": "npm run clean",
    "build": "webpack --mode production --colors --progress",
    "prestart": "npm run clean",
    "start": "webpack-dev-server --mode development --hot --colors --progress"
  },

webpack.config.js
const
  path = require('path'),
  fs = require('fs'),
  argv = require('yargs').argv,
  CopyWebpackPlugin = require('copy-webpack-plugin'),
  UglifyJsPlugin = require('uglifyjs-webpack-plugin'),
  MiniCssExtractPlugin = require('mini-css-extract-plugin'),
  OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'),
  HtmlWebpackPugPlugin = require('html-webpack-pug-plugin'),
  HtmlWebpackPlugin = require('html-webpack-plugin'),
  HashWebpackPlugin = require('hash-webpack-plugin'),
  WebpackChunkHash = require('webpack-chunk-hash');

const
  development = argv.mode === 'development',
  production = !development,
  mode = production ? 'production' : 'development',
  dest = path.join(__dirname, 'public_html'),
  assets = path.join(dest, 'assets'),
  src = path.resolve(__dirname, 'source'),
  node_modules = path.resolve(__dirname, 'node_modules');

const entries = {
  legacy: {
      'main': [
        '@babel/polyfill',
        './js/main.js'
      ],
      'jquery.selectric': node_modules + '/selectric/public/jquery.selectric.js'
      // ...
  }  
};

const 
  optimization = {
    minimizer: [
      new UglifyJsPlugin({
        sourceMap: true,
        uglifyOptions: {
          compress: {
            inline: false,
            warnings: false,
            drop_console: true,
            unsafe: true
          },
        },
      }),
      new OptimizeCSSAssetsPlugin({})
    ],
  },
  rules = [
    {
      test: /\.scss$/,
      use: [
        development ? 'style-loader' : MiniCssExtractPlugin.loader,
        {
          loader: 'css-loader',
          options: {
            minimize: production,
            url: false
          }
        },
        {
          loader: 'postcss-loader',
          options: {
            ident: 'postcss',
            plugins: [
              require('autoprefixer')({
                browsers: [
                  "last 4 version",
                  "ie 11"
                ],
              })
            ]
          }
        },
        'sass-loader'
      ]
    },
    {
      test: /\.js$/,
      exclude: /node_modules/,
      use: [
        {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env'],
            plugins: [
              '@babel/plugin-syntax-dynamic-import',
              '@babel/plugin-transform-runtime'
            ]
          }
        }
      ]
    }
  ],
  stats = {
    children: false, 
    assets: false,
    colors: true,
    version: false,
    hash: true,
    timings: true,
    chunks: false,
    chunkModules: false
  };

const ls = (dir, regexp = /\.pug/) => 
  fs.readdirSync(dir)
    .reduce((files, file) =>
      fs.statSync(path.join(dir, file)).isDirectory() ?
          files.concat(ls(path.join(dir, file), regexp)) :   
          (path.join(dir, file).match(regexp) ?       
            files.concat(path.join(dir, file)) : files
          ), 
      []
    );

let legacyPlugins = [];
ls(path.join(src, 'legacy', 'pug', 'pages')).forEach((fn) => legacyPlugins.push(
  new HtmlWebpackPlugin({
    template: fn,
    inject: false,
    filename: path.resolve(
      dest, 
      'legacy-' + path.basename(fn, '.pug').replace('/', '-') + '.html'
    )
  })
));

legacyPlugins.push(new HtmlWebpackPugPlugin());
if (production) {
  legacyPlugins.push(new HashWebpackPlugin({
    path: assets,
    'fileName': '.version'
  }));
}

ls(path.join(src, 'legacy', 'scss'), /\\[a-z0-9\-\.]+\.scss/).forEach((fn) => {
  let basename = path.basename(fn, '.scss'),
      name = path.basename(fn);
  entries.legacy[basename] = './scss/' + name;
});

let config = [ 
  {
    name: 'legacy',
    mode: mode,
    entry: entries.legacy,
    output: {
      publicPath: '/',
      filename: 'js/[name].js',      
      chunkFilename: 'js/[name].[chunkhash].js',
      path: path.join(assets, 'legacy'),
    },
    context: path.resolve(src, 'legacy'),
    module: {
      rules: rules.concat([{
        test: /\.pug$/,
        exclude: /node_modules/,
        use: [
          'html-loader',
          {
            loader: 'pug-html-loader',
            options: {
              pretty: production,
              data: require(path.resolve(src, 'legacy', 'demo.json'))
            }
          }
        ]
      }])
    },
    optimization: production ? optimization : {},      
    plugins: legacyPlugins.concat([
      new CopyWebpackPlugin(
        [
          {
            from: path.join(src, 'legacy', 'files'),
            to: dest,
            force: true
          },
          {
            from: path.join(src, 'legacy', 'svg'),
            to: path.join(assets, 'legacy', 'svg'),
            force: true
          }
        ], 
        { copyUnmodified: true }
      ),
      new MiniCssExtractPlugin({
        filename: 'css/[name].css',
        chunkFilename: "css/[id].css"
      }),
      new WebpackChunkHash({algorithm: 'md5'}),
      new webpack.HotModuleReplacementPlugin()
    ]),
    externals: {
      jquery: 'jQuery'
    },
    stats: stats,
    devServer: {
      contentBase: dest,
      publicPath: '',    
      port: 9000,
      compress: true,
      open: true,
      hot: true
    }
  }
];

module.exports = config;
Консоль
Child html-webpack-plugin for "..\..\legacy-404.html":
         1 asset
        Entrypoint html-webpack-plugin for "..\..\legacy-404.html" = ..\..\legacy-404.html
        [../../node_modules/html-webpack-plugin/lib/loader.js!./pug/pages/tech/404.pug] D:/Project/website/node_modules/html-webpack-plugin/lib/loader.js!./pug/pages/tech/404.pug 7.1 KiB {html-webpack-plugin for "..\..\legacy-404.html"} [built]

Размеется, в консоли выводится больше информации, но она связана со сборкой js и css. Без webpack-dev-server всё собирается, но работать, разумеется, тяжело.
  • Вопрос задан
  • 1215 просмотров
Решения вопроса 1
@codemafia Автор вопроса
Самоотвод
Минимальная конфигурация работает, но hrm не обновляет html автоматически (это логично). Скорее всего намудрил с путями в исходных настройках.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы