归纳webpack

常用配置项

const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通常用于生成HTML
const MiniCssExtractPlugin = require('mini-css-extract-plugin');// 用于分离CSS
const cssMinimizerWebpackPlugin = require("css-minimizer-webpack-plugin"); // 用于压缩CSS
{
  mode: 'development',
  devtool: 'source-map',
  entry: {
    // key: index作为打包后的产物名称 与output中的 【name】对应
    index: path.resolve(__dirname, './src/index.tsx')
  },
  // 类似在package.json中加上打包的-w命令 文件变动重新编辑
  watch:true,
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: 'js/[name].[contenthash:8].js',
    // const TipPage = import(/* webpackChunkName: "tipPage" */ '@/views/TipPage')  
    // 该组件打包后变成 tipPage.chunk.js
    chunkFilename: 'js/[name].chunk.js',
    assetModuleFilename: 'assets/[name].[contenthash][ext]',
    clean: true
  },
  resolve: {
    // 用于导入模块时不需要写出完整的文件名,(当文件名一样,后缀不一样时,按照从左到右的优先级读取文件)
    extensions: ['.ts', '.tsx', '.js', '.jsx'],
    alias: {
      '@': path.resolve(__dirname, './src'),
    },
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          //抽离css除了配置插件 还需配置该loader
          MiniCssExtractPlugin.loader,
          // ‘style-loader'
          {
            loader: "css-loader",
            options: {
              // esModule: true 搭配 namedExport: true 使用,
              esModule: false,
              modules: {
                mode: "local",
                // 如果引入样式 undefined 可加入该配置项 使样式可以默到处导出
                // namedExport: false,
                localIdentName: "[local]--[hash:base64:5]",
              },
            },
          },
          // 给需要兼容不同浏览器的样式加前缀 但需要配合postcss插件使用在postcss-config.js中配置
          "postcss-loader",
        ]
      },
      {
        test: /\.s[ac]ss$/,
        use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
      },
      //polyfill 支持js的降级在不同的浏览器中适用 需要使用corejs
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: {
            presets: [
              [
                "@babel/preset-env",
                {
                  targets: ["last 1 versions", "> 1%"],
                  useBuiltIns: "usage",
                  corejs: 3,
                },
              ],
            ],
          },
        },
      },
    ]
  },
  plugins: [
  	// 在组件中无需再引入react和loadsh
  	new webpack.ProvidePlugin({
      _: 'lodash',
      react: 'react'
    }),
    // 直接实例化插件
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: function (module) {
        // 将所有node_modules中的代码打包到vendor chunk中
        return module.context && module.context.includes('node_modules');
      }
    }),
    new HtmlWebpackPlugin({
      template: 'index.html',
      filename: "app.html",
      // 生成的js文件会在打包后的app.html的body中使用script引入
      inject: "body",
    }),
    // 抽离css 压缩css需要使用 cssMinimizerWebpackPlugin
    new MiniCssExtractPlugin({
      filename: 'styles/[contenthash:8].css'
    })
  ]
  // webpack编译的时候只输出错误和警告信息
  stats: 'errors-warnings',
  devServer: {
  	// 控制台只输出错误和警告信息
    stats: 'errors-warnings',
    hot: true,
    port: 3000,
    // 解决history路由刷新页面404问题。
    // Webpack Dev Server 在找不到路由对应的文件时,始终返回 index.html,以保证前端路由可以正确处理。
    historyApiFallback: true,
    proxy: {
      '/api': {
        target: 'http://localhost:8888',
        changeOrigin: true,
        pathRewrite: {
          '^/api': '',
        },
      },
    },
  client: {
    // 配置是否在浏览器中显示编译错误或警告的覆盖层
    overlay: false,
  },
  optimization: {
    // tree-shaking 极简主义 去掉所有未使用到的模块代码 第三方包除外
    usedExports: true,
    // 配合package.json中的sideEffects 只有css有副作用 其他代码会被删除
    //"sideEffects": [
    // "*.css"
    //],
  },
  },
  library: {
    name: "mylib",
    //umd支持node.js和浏览器,esm:export/import只支持浏览器,cjs适用nodejs,IIFE立即执行函数 支浏览器和node.js
    //浏览器(随着浏览器的发展,可以在script的标签中加入type="module"来支持)和nodejs(Node verison 13.2.0,有两种方式1:							  package.json中填写type: "modules",2.将文件结尾命名为mjs)
    type: "umd",
  },
  globalObject: "globalThis",
}

一般打包优化配置

{
  bail: true, // 在构建过程中遇到第一个错误时立即停止构建,并返回错误信息
  // 配置项包名不会被打包,而是直接从window中取(需要将忽略的包在index.html中引入)
  externals: {
    react: 'React',
    'react-dom': 'ReactDOM',
  },
  optimization:{
	 splitChunks: {
	   cacheGroups: {
	   	//node_modules[中的文件会被打包到定义好的chunkFilename即vender.js文件中
	     vendor: {
	       name: 'vendors',
	       test: /[\\/]node_modules[\\/]/,
	       chunks: 'all',
	     },
	     default: {
	       // 非node_modules产物打包后文件名由entry配置决定
	       minChunks: 2,
	       priority: -20,
	       reuseExistingChunk: true, // 复用打包好的模块
	     },
	   },
	 },
  },
  // 压缩css需要mode配置为production 否则不会进行压缩
  minimizer: [new cssMinimizerWebpackPlugin()],
}

缓存

// 内存缓存: 速度快,配置简单,但占用内存且重启后失效
cache: {
  type: 'memory',
}

// 磁盘缓存 (filesystem):持久性好,适合大型项目,但速度较慢,配置相对复杂。
cache: {
  type: 'filesystem',
  buildDependencies: {
    config: [__filename], // 配置文件的路径
  },
  cacheDirectory: path.resolve(__dirname, '.cache'), // 缓存目录
}

// 总结:
1、开发模式用内存缓存,电脑内存不够的误用;
2、生产模式用磁盘缓存,持久化缓存,进程重启后仍然可以使用缓存

postcss.config.js

module.exports = {
  // 自动给部分需要兼容的样式添加前缀
  plugins: [
    require("autoprefixer"),
    //允许css嵌套(当不在less等css预编译器中时 支持嵌套)
    require("postcss-nested"),
  ],
};

多页面配置

entry: {
  main: {
    import: ["./src/app.js", "./src/app2.js"],
    // 这样配置 即使app.js用到了lodash 也不会打包lodash到main.js产生的bundle中
    dependOn: "lodash",
    // bundle输出路径
    filename: "channel1/[name].[contenthash:8].js",
  },
  main2: {
    import: "./src/app3.js",
    dependOn: "lodash",
    filename: "channel2/[name].[contenthash:8].js",
  },
  // lodash: "lodash",
  lodash: {
    import: "lodash",
    filename: "common/[name].js",
  },
},
output: {
  // entry若配置了filename 优先级大于此处
  filename: "[name].[contenthash:8].js",
  clean: true,
},
plugins: [
  new HtmlWebpackPlugin({
    // 配合模版中的<%= htmlWebpackPlugin.options.title %>使用
    // eg: <%= htmlWebpackPlugin.options.title %>
    title: "多页面应用test",
    template: "./index.html",
    inject: "body",
    filename: "channel1/index.html",
    // 配置根据模版生成的index.html中引入的chunk
    chunks: ["main", "lodash"],
    publicPath: "http://www.a.com/",
  }),
  new HtmlWebpackPlugin({
    template: "./index2.html",
    inject: "body",
    filename: "channel2/index2.html",
    chunks: ["main2", "lodash"],
    publicPath: "http://www.b.com/",
  }),
],

你可能感兴趣的:(webpack,前端)