核心概念

  1. 入口(entry)
  2. 输出(output)
  3. loader
  4. 插件(plugins)


entry

构建依赖图的起始位置

output

bundle输出位置

loader

处理非javascript文件

plugins

执行任务,如打包、压缩等

配置依赖图

  1. module.exports = {
  2. //单个入口(简写)语法
  3. entry: string|Array<string>,
  4. //对象语法
  5. entry: {[entryChunkName: string]: string|Array<string>},
  6. //基本配置
  7. output: {
  8. filename: string,
  9. path: string,
  10. },
  11. mode: string, // development|production|其他
  12. };

常用插件

  • HtmlWebpackPlugin
  • mini-css-extract-plugin 抽离css样式

    常用loader

  • babel-loader 转换js语法

  • ESLint Loader 校验js代码
  • style-loader html插入style标签
  • css-loader 处理css
  • postcss-loader 处理css 如加上浏览器前缀
  • less-loader 处理less
  • expose-loader 全局变量引入

    处理JS文件

    babel-loader处理js语法,eslint-loader开发环境代码校验,相关依赖包如下:
    @babel/core
    @babel/preset-env // es6语法
    @babel/plugin-transform-runtime
    @babel/plugin-proposal-decorators
    @babel/plugin-proposal-class-properties
    babel-loader

    babel-loader

    1. {
    2. test: /\.m?js$/,
    3. exclude: /(node_modules|bower_components)/,
    4. use: {
    5. loader: 'babel-loader',
    6. options: {
    7. presets: ['@babel/preset-env'],
    8. plugins: [
    9. '@babel/plugin-transform-runtime', // function *
    10. ["@babel/plugin-proposal-decorators", { legacy: true }], // 解析注解
    11. "@babel/plugin-proposal-class-properties" // 解析class
    12. ]
    13. }
    14. }
    15. }

    eslint-loader

    处理样式资源

    处理图片资源

    file-loader、url-loader处理文件

    file-loader

    1. //es6或者CommonJS引入文件
    2. import file from "file.png";
    3. //背景图片
    4. {
    5. background-image: url("../images/1234.png");
    6. }
    7. // 配置信息
    8. {
    9. test: /\.(jpe?g|png|gif|svg)$/i,
    10. use: [
    11. {
    12. loader: 'file-loader',
    13. options: {
    14. name:'[path][name]_[hash:8].[ext]',
    15. outputPath: "/images",
    16. // publicPath: "http://www.url.cn", 生产环境cdn配置
    17. }
    18. },
    19. ]
    20. },

    url-loader

    1. module.exports = {
    2. module: {
    3. test: /\.(jpe?g|png|gif|svg)$/i,
    4. use: [{
    5. loader: 'url-loader',
    6. options: {
    7. //当加载的图片小于limit时,会将图片编译成base64字符串的形式,
    8. //当图片大于这个limit,会用file-loader进行加载
    9. limit: 130000,
    10. //在webpack4.x必须显式的指定fallback备用方法,这里指定为file-loader
    11. fallback: require.resolve('file-loader'),
    12. encoding: "base64",
    13. //这个表示在打包生成的文件的名字,如果不配置这个,会根据hash生成一个名字,这个配置就是自定义命名规则
    14. //这个表示会在输出文件夹dist下创建一个img文件夹,所有的文件会以 “原名字+hash值8位+文件扩展名”生成最终的文件来供使用
    15. name: "img/[name].[hash:8].[ext]",
    16. },
    17. }]
    18. }
    19. }

    引入全局变量

    打包多页面

    1. const path = require("path");
    2. const HtmlWebpackPlugin = require("html-webpack-plugin");
    3. module.exports = {
    4. mode: "development", // development production
    5. entry: {
    6. core: "./src/entry/core/core.js",
    7. locate: "./src/entry/locate/locate.js",
    8. },
    9. output: {
    10. filename: "[name].js",
    11. path: path.resolve(__dirname, "dist")
    12. },
    13. // HtmlWebpackPlugin 一个实例打包一个html
    14. plugins: [
    15. new HtmlWebpackPlugin({
    16. template: "./src/entry/core/core.html",
    17. filename: "core.html",
    18. chunks: ["core"]
    19. }),
    20. new HtmlWebpackPlugin({
    21. template: "./src/entry/locate/locate.html",
    22. filename: "locate.html",
    23. chunks: ["locate"]
    24. })
    25. ]
    26. };

    打包前清除打包目录文件、复制公共文档

    1. const { CleanWebpackPlugin } = require("clean-webpack-plugin");
    2. module.exports = {
    3. plugins: [
    4. new webpack.ProgressPlugin(),
    5. new CleanWebpackPlugin(), // 清除output
    6. // 复制public 到 output目录下
    7. new CopyWebpackPlugin({
    8. patterns: [{ from: './src/public', to: './public' }]
    9. }),
    10. new HtmlWebpackPlugin({
    11. template: "./src/entry/core/core.html",
    12. filename: "core.html",
    13. chunks: ["core"]
    14. }),
    15. new HtmlWebpackPlugin({
    16. template: "./src/entry/locate/locate.html",
    17. filename: "locate.html",
    18. chunks: ["locate"]
    19. }),
    20. ]
    21. }

    解析文件路径

    1. import xx from 'abc';
    2. module.exports = {
    3. resolve: {
    4. modules: ["node_modules", path.resolve(__dirname, "src")],// node_modules优先寻找
    5. mainFields: ["browser", "module", "main"], // 重abc库的package.json 配置文件中优先寻找browser
    6. // import bb from './index' 匹配index.js index.css index.vue index.json
    7. extensionsextensions: [".js", ".css", ".vue", ".json"],//
    8. }
    9. }

    定义环境变量

    DefinePlugin, webpack 内置的插件
    1. const webpack require('webpack');
    2. module.exports = {
    3. plugins: [
    4. new webpack.DefinePlugin({
    5. PRODUCTION: JSON.stringify(true),
    6. VERSION: JSON.stringify("5fa3b9"),
    7. BROWSER_SUPPORTS_HTML5: true,
    8. TWO: "1+1",
    9. "typeof window": JSON.stringify("object")
    10. })
    11. ]
    12. };
    13. // index.js
    14. if (PRODUCTION) {
    15. log('11111');
    16. } else {
    17. log('22222');
    18. }

拆分配置文件

  1. // webpack.

构建性能提升

  1. module.noParse配置,

    1. module.exports = {
    2. module: {
    3. noParse: /jquery/, /* import $ from "jquery" // 不解析jquery的依赖 */
    4. }
    5. }
  2. module.rules[index] exclude、include配置

    1. module.rules[index] = {
    2. exclude: [path.resolve(__dirname, 'node_modules')] | /node_modules/,
    3. include: [path.resolve(__dirname, 'src')] | /src/
    4. }
  3. IgnorePlugin

    1. new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), // 不导入moment/locale 下的所有文件
  4. DllPlugin拆分文件, 如拆分react + react-dom文件, 不必每次都打包 ```javascript // webpack.config.react.js const path = require(“path”); const wabpack = require(“webpack”); module.exports = { mode: “development”, // production、 development devServer: { port: 9015, }, entry: { react: [“react”, “react-dom”] }, output: { filename: “dll[name].js”, path: path.resolve(dirname, “dist”), library: “dll[name]”, libraryTarget: “var”, // var,commomjs,umd }, plugins: [ new wabpack.DllPlugin({ name: “dll[name]”, path: path.resolve(dirname, ‘dist’, “manifest.json”) }) ], };

// webpack.config.js const HtmlPlugin = require(“html-webpack-plugin”); const path = require(“path”); const webpack = require(“webpack”); module.exports = { mode: “development”, // production、 development devServer: { port: 9015, }, entry: { main: “./src/index.js” }, output: { filename: “[name].js”, path: path.resolve(dirname, “dist”) }, plugins: [ new HtmlPlugin({ template: “./public/index.html”, filename: “index.html” }), // 引用动态库 new webpack.DllReferencePlugin({ manifest: path.resolve(dirname, ‘dist’, ‘manifest.json’) }) ], } // src/index.js import React from “react”; import ReactDom from “react-dom”; class App extends React.Component { constructor() { super();

} render() { return (

Long time no see! React!
) } } ReactDom.render(React.createElement(App), document.getElementById(‘app’));

  1. 5. happypack多线程打包
  2. moduleplugins部分
  3. ```javascript
  4. const HtmlPlugin = require("html-webpack-plugin");
  5. const path = require("path");
  6. const webpack = require("webpack");
  7. const Happypack = require("happypack");
  8. module.exports = {
  9. mode: "development", // production、 development
  10. devServer: {
  11. port: 9015,
  12. },
  13. entry: {
  14. main: "./src/index.js"
  15. },
  16. output: {
  17. filename: "[name].js",
  18. path: path.resolve(__dirname, "dist")
  19. },
  20. plugins: [
  21. new HtmlPlugin({
  22. template: "./public/index.html",
  23. filename: "index.html"
  24. }),
  25. new webpack.DllReferencePlugin({
  26. manifest: path.resolve(__dirname, 'dist', 'manifest.json')
  27. }),
  28. new Happypack({
  29. loaders: [
  30. {
  31. loader: "babel-loader",
  32. options: {
  33. presets: [
  34. "@babel/env",
  35. "@babel/react",
  36. ],
  37. plugins: [
  38. "@babel/plugin-proposal-class-properties"
  39. ]
  40. }
  41. }
  42. ]
  43. })
  44. ],
  45. module: {
  46. noParse: /jquery/,
  47. rules: [
  48. {
  49. test: /\.js$/i,
  50. use: "happypack/loader",
  51. include: /src/,
  52. exclude: /node_modules/
  53. }
  54. ]
  55. }
  56. };
  1. webpack自带优化
    1. 使用export import引用会自动过滤没有使用的代码,打包体积小(require不会过滤)tree-shaking
  2. optimization抽离公共模块

    1. module.exports = {
    2. optimization: {
    3. splitChunks: {
    4. cacheGroups: {
    5. common: {
    6. chunks: "initial",
    7. minSize: 0,
    8. minChunks: 2,// 重复两次以上
    9. },
    10. vendor: {
    11. test: /node_modules/,
    12. chunks: "initial",
    13. priority: 1,// 设置优先级 先抽离第三方
    14. minSize: 0,
    15. minChunks: 2,
    16. }
    17. }
    18. }
    19. },,
    20. }
  3. import懒加载

    1. import('url').then(res => {
    2. console.log(res.default);
    3. });