前端開發 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",


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM