• 前端开发 webpack 通用配置


    以后公司前端新项目 webpack 可以选择使用这一套通用配置,该配置满足了一下诸多功能。

    使用者可以自己定义一些 loader 以及 plugin 以满足日常开发需要,在下面给出详细的注释以便理解与使用。(开发时可以把注释删掉)

    - webpack.base.js

    // webpack.base.js用于通用的 webpack 配置
    
    // 自动适配浏览器前缀
    const autoprefixer = require('autoprefixer');
    // 用于多页面入口打包,
    const glob = require('glob');
    // 获取路径
    const path = require('path');
    // 自动清除输出目录插件
    const CleanWebpackPlugin = require('clean-webpack-plugin');
    // webpack 打包出错 terminal log 插件
    const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin');
    // 引入外部资源,申生成入口插件
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    // 将 CSS 提取为独立的文件的插件
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    // 获取项目根目录
    const projectRoot = process.cwd();
    
    // 多页面应用入口程序,通过匹配获取对应页面入口,单页面可以直接定义 entry 就行
    const setMPA = () => {
      const entry = {};
      const htmlWebpackPlugins = [];
      const entryFiles = glob.sync(path.join(projectRoot, './src/*/index.js'));
    
      Object.keys(entryFiles)
        .map((index) => {
          const entryFile = entryFiles[index];
          // '/Users/buzhuo/my-project/src/index/index.js'
          const match = entryFile.match(/src/(.*)/index.js/);
          const pageName = match && match[1];
          entry[pageName] = entryFile;
          return htmlWebpackPlugins.push(
            new HtmlWebpackPlugin({
              inlineSource: '.css$',
              template: path.join(projectRoot, `./src/${pageName}/index.html`),
              filename: `${pageName}.html`,
              chunks: ['vendors', pageName],
              inject: true,
              minify: {
                html5: true,
                collapseWhitespace: true,
                preserveLineBreaks: false,
                minifyCSS: true,
                minifyJS: true,
                removeComments: false,
              },
            })
          );
        });
    // 返回入口以及入口对应的 htmlWebpackPlugins
      return {
        entry,
        htmlWebpackPlugins,
      };
    };
    
    const { entry, htmlWebpackPlugins } = setMPA();
    
    module.exports = {
      entry: entry,
      output: {
        path: path.join(projectRoot, 'dist'),
        filename: '[name]_[chunkhash:8].js'
      },
      module: {
        rules: [
          {
            test: /.js$/,
            use: [
              {
                loader: 'babel-loader'
              }
            ],
          },
          {
            test: /.css$/,
            use: [
              MiniCssExtractPlugin.loader,
              'css-loader',
            ],
          },
          {
            test: /.less$/,
            use: [
              MiniCssExtractPlugin.loader,
              'css-loader',
              'less-loader',
              {
                // CSS预处理
                loader: 'postcss-loader',
                options: {
                  plugins: () => [
                    autoprefixer({
                      browsers: ['last 2 version', '>1%', 'ios 7'],
                    }),
                  ],
                },
              },
              {
                // px 自动转换为 rem 移动端,若无移动端需求该 loader 可删去
                loader: 'px2rem-loader',
                options: {
                  remUnit: 75,
                  remPrecision: 8,
                },
              },
            ],
          },
          {
            test: /.(png|jpg|gif|jpeg)$/,
            use: [
              {
                loader: 'file-loader',
                options: {
                  name: '[name]_[hash:8].[ext]',
                },
              },
            ],
          },
          {
            test: /.(woff|woff2|eot|ttf|otf)$/,
            use: [
              {
                loader: 'file-loader',
                options: {
                  name: '[name]_[hash:8][ext]',
                },
              },
            ],
          },
        ],
      },
      plugins: [
        new MiniCssExtractPlugin({
          filename: '[name]_[contenthash:8].css',
        }),
        new CleanWebpackPlugin(),
        new FriendlyErrorsWebpackPlugin(),
        function errorPlugin() {
          this.hooks.done.tap('done', (stats) => {
          if (stats.compilation.errors && stats.compilation.errors.length && process.argv.indexOf('--watch') === -1) {
              process.exit(1);
          }
          });
        },
      ].concat(htmlWebpackPlugins),
      // webpack 在打包时仅出错才会输出到 terminal,具体参数可到https://webpack.js.org/查看
      stats: 'errors-only',
    };
    

    - webpack.dev.js

    // merge 用来合并 webpack.base.js 与 webpack.dev.js
    const merge = require('webpack-merge');
    const webpack = require('webpack');
    const baseConfig = require('./webpack.base');
    
    const devConfig = {
      mode: 'production',
      plugins: [
        // 生产环境下开启热加载插件
        new webpack.HotModuleReplacementPlugin(),
      ],
    devServer: {
        // 指定 devServer 相关,在此可以指定 port 等配置
      contentBase: './dist',
        hot: true,
        stats: 'errors-only',
      },
      // 该参数见下图
      devtool: 'cheap-source-map',
    };
    
    module.exports = merge(baseConfig, devConfig);
    
    

    - webpack.prod.js

    webpack 4.0 以上将 uglifyjs 与 treeshaking 设为 webpack 默认,只要设置mode = production 就默认开启

    // css 压缩插件
    const cssnano = require('cssnano');
      // merge webpack.dev.js 与 webpack.prod.js
    const merge = require('webpack-merge');
      // 用于 cdn 加速 react,引用外部资源
    const HtmlWebpackExternalsPlugin = require('html-webpack-externals-plugin');
      // 提取 css 到单独文件并且压缩 css
    const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
      // 前面提到的基本配置
    const baseConfig = require('./webpack.base');
    
    const prodConfig = {
      mode: 'production',
      plugins: [
        new OptimizeCSSAssetsPlugin({
          assetNameRegExp: /.css$/g,
          cssProcessor: cssnano,
        }),
        new HtmlWebpackExternalsPlugin({
          externals: [
            {
              module: 'react',
              entry: 'https://11.url.cn/now/lib/16.2.0/react.min.js',
              global: 'React',
            },
            {
              module: 'react-dom',
              entry: 'https://11.url.cn/now/lib/16.2.0/react-dom.min.js',
              global: 'ReactDOM',
            },
          ],
        }),
      ],
      // code split
      optimization: {
        splitChunks: {
        minSize: 0,
          cacheGroups: {
            commons: {
              name: 'vendors',
              chunks: 'all',
              minChunks: 2,
            },
          },
        },
      },
    };
    
    module.exports = merge(baseConfig, prodConfig);
    
    

    所需依赖

    autoprefixer
    babel-loader
    clean-webpack-plugin
    css-loader
    cssnano
    eslint-loader
    file-loader
    friendly-errors-webpack-plugin
    glob
    html-inline-css-webpack-plugin
    html-loader
    html-webpack-externals-plugin
    html-webpack-inline-source-plugin
    html-webpack-plugin
    less
    less-loader
    mini-css-extract-plugin
    node-notifier
    optimize-css-assets-webpack-plugin
    postcss-loader
    postcss-preset-env
    px2rem-loader
    raw-loader
    react
    react-dom
    style-loader
    uglifyjs-webpack-plugin
    url-loader
    webpack
    webpack-cli
    webpack-merge
    

    执行命令

    在项目根目录下的 package.json 的 scripts 里新增脚本:

    开发环境 && 生产环境

    "dev": "webpack-dev-server --config webpack.dev.js --open",
    "build": "webpack --config webpack.prod.js",
    
  • 相关阅读:
    英特尔®oneAPI简介及动手实验研讨会召集令
    发展壮大:帮助独立游戏开发商解决分销难题
    我们可以从英特尔® SPMD 程序编译器中学到什么?
    2019 Unreal Open Day —— 英特尔携手 UE 助力游戏开发生态建设
    Abp集成Quartz.net记录
    静态和实例初始化映射
    Queryable扩展点
    投影
    空类型映射
    列表和数组
  • 原文地址:https://www.cnblogs.com/ssaylo/p/13710172.html
Copyright © 2020-2023  润新知