一篇搞懂Webpack常用的配置

一篇搞懂Webpack常用的配置

  • 我的社交平台 有问题可以在这里留言呀
  • github
  • 博客

1.认识 Webpack

Webpack 是什么?

  • 官方的定义
    • Webpack 是一个用于现代 JavaScript 应用程序的 静态模块打包工具。
    • Webpack 处理应用程序时,
    • 它会在内部从一个或多个入口点构建一个 依赖图(dependency graph)
    • 然后将你项目中所需的每一个模块组合成一个或多个 bundles,它们均为静态资源,用于展示你的内容
  • 简单的说
    • 之前
      • 2010年左右,前端当时还是利用 jQuery 进行开发
      • 后端利用 php jsp 等技术将数据库的数据渲染到前端的页面上
      • 前后端开始是耦合的 维护和开发 都是一个不规范 繁琐的流程
    • 现在
      • 当三大框架的横行后 逐渐以MVVM(Model-View-ViewModel)模式来
      • 减少繁琐的 DOM 操作,以数据来驱动视图的变化,更加利于维护和开发
    • 为什么使用
      • 原生js不会提供所有的特性, 因此就需要引入各种插件
      • Webpack就是大一统的集成方案

Webpack 可以做什么

  • 使用Webpack作为前端构建工具通常可以做到以下几个方面的事情
    • 代码转换: TypeScript编译成JavaScriptSCSS编译成CSS等。
    • 文件优化: 压缩JavaScriptCSSHTML代码,压缩合并图片等。
    • 代码分割: 提取多个页面的公共代码、提取首屏不需要执行部分的代码让其异步加载。
    • 模块合并: 在采用模块化的项目里会有很多个模块和文件,需要构建功能把模块分类合并成一个文件。
    • 自动刷新: 监听本地源代码的变化,自动重新构建、刷新浏览器页面,通常叫做模块热替换HMR
    • 代码校验: 在代码被提交到仓库前需要校验代码是否符合规范,以及单元测试是否通过。
    • 自动发布: 更新完代码后,自动构建出线上发布代码并传输给发布系统。

2.搭建 Webpack

搭建基本环境

  • 安装最新的环境, 新建一个文件夹叫 test
  • test 根路径下载基本的依赖
yarn add webpack webpack-cli --save-dev
yarn add webpack-dev-server -D
yarn add html-webpack-plugin --save-dev
  • test/package.json 文件添加启动和打包的 shell 命令
"scripts": {
    "serve": "webpack serve ",
    "build": "webpack"
},
  • 新建基本的文件
# dist 目录不用手动创建 这个是打包自动生成的
|-- node_modules
├── dist
│   └── main.js
├── public
│   └── index.html
├── package.json
├── src
│   └── index.js
└── webpack.config.js
  • 在 webpack.config.js 文件写入基本的配置
# 这些配置后面会具体解释 这里主要配置了打包的出口文件和入口文件
# webpack.config.js
const path = require('path')
module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist'),
  },
  mode: "development"
}

测试

此时就完成了基本的搭建,可以来使用shell语句测试一下效果了
  • /src/index.js 写入 console.log('Hello Webpck');
  • 然后在项目根路径执行之前在package.json定义的shell命令
  • yarn build 就在在 /dist/main.js 发现转换后的代码了
  • 但是目前还是不能展示html页面 和 启动服务
  • 在下一阶段就将安装两个必要的插件
/*
 * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
 * This devtool is neither made for production nor for readable output files.
 * It uses "eval()" calls to create a separate source file in the browser devtools.
 * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
 * or disable the default devtool with "devtool: false".
 * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
 */
/******/ (() => { // webpackBootstrap
/******/ 	var __webpack_modules__ = ({

/***/ "./src/index.js":
/*!**********************!*\
  !*** ./src/index.js ***!
  \**********************/
/***/ (() => {

eval("console.log('Hello Webpck');\n\n//# sourceURL=webpack:///./src/index.js?");

/***/ })

/******/ 	});
/************************************************************************/
/******/ 	
/******/ 	// startup
/******/ 	// Load entry module and return exports
/******/ 	// This entry module can't be inlined because the eval devtool is used.
/******/ 	var __webpack_exports__ = {};
/******/ 	__webpack_modules__["./src/index.js"]();
/******/ 	
/******/ })()
;

3.配置插件

导读

  • 自己可以去npm 搜索各种loader 获取更多具体的配置
  • 这里仅仅配置了我用过的常用配置
  • npm-loader
  • 配置插件章节的项目最终结构
目录结构
.
├── dist
│   ├── index.html
│   ├── main.js
│   └── public
│       ├── assets
│       │   └── images
│       │       └── 99b6d6d0aac2e1ab068e.png
│       └── static
│           └── e7c3da3c784524f42673.html
├── node_modules
├── package.json
├── public
│   ├── avatar.png
│   └── index.html
├── src
│   ├── index.js
│   └── index.less
└── webpack.config.js
index.html
./public/index.html
<body>
  html5
  <img id='im' src="" alt="">
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
  </ul>
</body>
index.js
# ./src/index.js
import avatar from '../public/avatar.png'
import './index.less'
const im = document.getElementById('im')
im.src = avatar
console.log('Hello Webpck');
const aaaa = () => 10
console.log(aaaa);
index.less
# ./src/index.less
@myColor: blue;
li{
  color: @myColor;
}
webpack.config.js
# ./webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist'),
    // 指定打包后输出的文件夹 ./dist/public/assets/images
    assetModuleFilename: 'public/assets/images/[hash][ext][query]'
  },
  mode: "development",
  devServer: {
    // 启动gzip压缩
    compress: true,
    port: 8088,
    open: true
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './public/index.html',
      //要生成的文件名 存在内存 目录中不显示
      filename: 'index.html',
      minify: {
        // 移除空格
        collapseWhitespace: true,
        // 移除注释
        removeComments: true
      }
    })
  ],
  module: {
    rules: [
      {
        test: /\.(?:ico|gif|png|jpg|jpeg)$/i,
        type: 'asset/resource',
      },
      // {
      //   test: /\.html/,
      //   type: 'asset/resource',
      //   generator: {
      //     filename: 'public/static/[hash][ext][query]'  // 单独指定名字
      //   }
      // },
      {
        test: /\.svg/,
        type: 'asset/inline'  // inline 的时候不需要指定文件名
      },
      {
        test: /\.txt/,
        type: 'asset',
        parser: {
          dataUrlCondition: {
            maxSize: 4 * 1024 // 4kb  指定大小
          }
        }
      },
      {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      },
      {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader',
          'postcss-loader'
        ]
      },
      {
        test: /\.less$/,
        use: [
          'style-loader',
          'css-loader',
          'less-loader',
        ]
      },
      {
        test: /\.scss$/,
        use: [
          'style-loader',
          'css-loader',
          'sass-loader'
        ]
      }
    ],
  },
}
package.json
# package.json
{
  "scripts": {
    "serve": "webpack serve",
    "build": "webpack"
  },
  "dependencies": {
    "html-webpack-plugin": "^5.5.0",
    "webpack": "^5.69.0",
    "webpack-cli": "^4.9.2"
  },
  "devDependencies": {
    "@babel/core": "^7.17.4",
    "@babel/plugin-proposal-class-properties": "^7.16.7",
    "@babel/preset-env": "^7.16.11",
    "autoprefixer": "^10.4.2",
    "babel-loader": "^8.2.3",
    "css-loader": "^6.6.0",
    "less": "^4.1.2",
    "less-loader": "^10.2.0",
    "node-sass": "^7.0.1",
    "postcss-loader": "^6.2.1",
    "sass-loader": "^12.6.0",
    "style-loader": "^3.3.1",
    "webpack-dev-server": "^4.7.4"
  }
}

webpack-dev-server

  • 这个插件其实就是一个小型的本地服务器
  • 相关配置也比较简单
  • 其他的具体配置后面再说
  • 这时候就可以执行 yarn serve
  • 此时还没有配置解析html的插件 因此先手动跳转到 main.js 测试下
  • http://localhost:8088/main.js
yarn add webpack-dev-server -D
# webpack.config.js
const path = require('path')
module.exports = {
  ...
  devServer: {
    // 启动gzip压缩
    compress: true,
    // 打开的端口
    port: 8088,
    // 启动服务后自动打开网页
    open: true
  }
}

html-webpack-plugin

  • 这个包显然就是用来解析html的
  • 配置后运行 yarn build 就可以在 dist 目录看到打包后的 index.html
  • 同时运行 yarn serve 也可以直接运行解析了
yarn add html-webpack-plugin -D
# 在 ./public/index.html 随便写点东西
<body>
  html5
  <img id='im' src="" alt="">
</body>
# webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist'),
  },
  mode: "development",
  devServer: {
    // 启动gzip压缩
    compress: true,
    port: 8088,
    open: true
  },
  plugins: [
    new HtmlWebpackPlugin({
      // 要生成的index.html路径 
      template: './public/index.html',
      //要生成的文件名 存在内存 目录中不显示
      filename: 'index.html',
      minify: {
        // 移除空格
        collapseWhitespace: true,
        // 移除注释
        removeComments: true
      }
    })
  ]
}
此时我们完成了基本的架构,现在需要配置各种loader来满足项目的需要

Asset Modules

  • Asset Modules 是一种模块,它允许人们在不配置额外加载器的情况下使用资产文件(字体、图标等)
  • webpack5 不需要再去手动下载三个loader
  • webpack 5 之前,通常使用:
    • raw-loader将文件作为字符串导入
    • url-loader将文件作为数据 URI 内联到包中
    • file-loader将文件发送到输出目录
  • Asset Modules 分为4中资源模块
    • asset/resource 将资源分割为单独的文件,并导出url,就是之前的 file-loader的功能
    • asset/inline 将资源导出为dataURL(url(data:))的形式,之前的 url-loader的功能
    • asset/source 将资源导出为源码(source code). 之前的 raw-loader 功能
    • asset 自动选择导出为单独文件或者 dataURL形式(默认为8KB). 之前有url-loader设置asset size limit 限制实现。
  • 当配置完成后运行 yarn build就会发现 图片也被打包进了dist目录
# 在 ./public 放一张图片 这里选择了avatar.png
# ./src/index.js 
import avatar from '../public/avatar.png'
const im = document.getElementById('im')
im.src = avatar
console.log('Hello Webpck');
# webpack.config.js => module.exports.use
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist'),
    // 指定打包后输出的文件夹 ./dist/public/assets/images
    assetModuleFilename: 'public/assets/images/[hash][ext][query]'
  },
  mode: "development",
  devServer: {
    // 启动gzip压缩
    compress: true,
    port: 8088,
    open: true
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './public/index.html',
      //要生成的文件名 存在内存 目录中不显示
      filename: 'index.html',
      minify: {
        // 移除空格
        collapseWhitespace: true,
        // 移除注释
        removeComments: true
      }
    })
  ],
  module: {
    rules: [
      {
        test: /\.(?:ico|gif|png|jpg|jpeg)$/i,
        type: 'asset/resource',
      },
      // {
      //   test: /\.html/,
      //   type: 'asset/resource',
      //   generator: {
      //     filename: 'public/static/[hash][ext][query]'  // 单独指定名字
      //   }
      // },
      {
        test: /\.svg/,
        type: 'asset/inline'  // inline 的时候不需要指定文件名
      },
      {
        test: /\.txt/,
        type: 'asset',
        parser: {
          dataUrlCondition: {
            maxSize: 4 * 1024 // 4kb  指定大小
          }
        }
      }
    ],
  },
}

babel-loader

  • babel-loader 用于转化和识别高级语法
  • 当配置完成后运行 yarn build 可以查看 ./dist/main.js 后可以发现
    • 代码已经将箭头函数转换成了es5
    • var aaaa = function aaaa() {\n return 10;\n};\n\nconsole.log(aaaa);
    • 然后注销掉 babel-loader 的规则 重新打包
    • 你会发现 main.js 中还是箭头函数 这就是 babel-loader 的作用之一
npm install -D babel-loader @babel/core @babel/preset-env 
在 ./src/index.js 加入一个 es6 箭头函数
const aaaa = () => 10
console.log(aaaa);
# webpack.config.js => module.exports.module.rules.xxx
{
  test: /\.js$/,
  exclude: /(node_modules|bower_components)/,
  use: {
    loader: 'babel-loader',
    options: {
      presets: ['@babel/preset-env']
    }
  }
},

css,sass,less,postcss loader

  • sass less 大家都知道是css的预编译语言就不用多说了
  • postcss 是用于自动添加css的兼容前缀
  • 接下来就一次性安装多个loader
    • 不过注意 node-sass 的上游依赖需要手动配置镜像或代理 否则一直可能下载失败
      {% btn ‘https://www.ydyno.com/archives/1219.html’,node-sass配置镜像,far fa-hand-point-right,blue larger %}
  • 配置完成后 就可以看到less-loader生效了
  • 其他的loader,可以自己测试下,这里就不测试了
yarn add style-loader css-loader -D 
yarn add less-loader less -D
yarn add sass-loader node-sass -D
yarn add postcss-loader autoprefixer -D
# ./public/index.html 
ul>li{$}*3
# ./src/index.js
import './index.less'
# ./src/index.less
@myColor: blue;
li{
  color: @myColor;
}
# webpack.config.js => module.exports.module.rules.xxx
    {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader',
          'postcss-loader'
        ]
      },
      {
        test: /\.less$/,
        use: [
          'style-loader',
          'css-loader',
          'less-loader',
        ]
      },
      {
        test: /\.scss$/,
        use: [
          'style-loader',
          'css-loader',
          'sass-loader'
        ]
      }

4. configuration

版本事项

以下的这些配置基于 webpack 4.x, 当使用webpack5 时可能有一些变动

webpack4.x
webpack5

entry

# 新建目录src
    默认入口: ./src/index.js
#
  多入口打包 
  entry: {
    'jquery': './src/index.js',
    'angular': './src/2.js'
  },
# 根目录创建webpack.config.js
 // entry: string   生成一个chunk 输出一个 bundle
 // entry: sring[]  生成一个chunk 输出一个 bundle
 // entry: object   有几个入口文件就生成几个 chunk 和 bundle 
module.exports = {
  entry: "./src/main.js", 
} 

output

  默认出口: ./dist/main.js
#
module.exports = {
  output: { 
    path: path.join(__dirname, "dist"),
    filename: "bundle.js",
    // 资源公众路径前缀 
    // images/a.jpg => /images/a.jpg
    publicPath: '/',
    chunkFilename: 'js/[name]_chunk.js',
    // 整个库向外保留的变量名
    library: '[name]'
    // 变量名添加到顶级作用域 global
    libraryTarget: 'window'            
 },
}

mode

module.exports = {
  mode: 'development production' 
} 

devServer

module.exports = {
  port: 5000,
  host: 'localhost',
  open: true,
  hot: true,
  proxy: {
 /* 
 本地 :5000 端口服务器接受到 /api/xxx 的请求
 就会把请求转发到另外一个服务器 :3000
 */
    '/api': {
       target: 'http://localhost:3000',
  // 请求路径重写:将 /api/xxx --> /xxx (去掉/api)
       pathRewrite: {
         '^/api': ''
       }
     }
  }
  
  // 不显示服务器日志信息
  clientLogLevel: 'none',
  // 除了一些基本启动信息以外,其他内容都不要显示
  quiet: true,
  // 如果报错 不要全屏提示
  overlay: false
  // 启动gzip压缩
  compress: true,  
  watchContentBase: true,
  watchOptions: {
          // 忽略文件
          ignored: /node_modules/
  },
  
  # 4.0 webpack
  // 影响本地资源的访问  express.static
  // 是对 output 打包文件物理存储位置的映射
  publicPath: "/assets/",
  // html页面的路径 (默认就是项目根路径) 
  // 初始相对路径是webpack.config 如果dist和他同级 
  // contentBase: './dist'
  contentBase: resolve(__dirname, 'dist')
  // 监视 contentBase 目录下的所有文件 文件变化就会 reload
  # 5.0 webpack
  // 默认指定为 public 目录
  static: { //false
    directory: path.join(__dirname, 'assets'),
    publicPath: '/index.html',
  }
}

module

noParse
module.exports = {
  // 防止 webpack 解析这些文件 
  // 这些文件内不能含有 import require define
  // 可以提高性能
  module: {
    noParse: /jquery|lodash/
  }
}
rules
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
      {
        test: /\.js$/
        // 排除 node_modules 下的js文件
        exclude: /node_modules/,
        // 只检查 src 下的js文件
        include: resolve(__dirname, 'scr'),
        // pre:优先执行 post:延后执行
        enforce: 'pre',
        loader: 'eslint-loader',
        options: { }
      },
      {
        // 当规则匹配时 只使用第一个成功的匹配规则
        oneOf: [
          {
            
          }
        ]
       }
    ]
  }
}
oneOf
// 当规则匹配时 只使用第一个成功的匹配规则
module.exports = {
  module:{
    rules:[
      {
        oneOf: [
          {
              test: /\.(jpg|png|gif)/,
              loader: 'url-loader',
              options: {
                limit: 8 * 1024,
                name: '[hash:10].[ext]',
                outputPath: 'imgs',
                esModule: false
              }
           },
           {
              test: /\.html$/,
              loader: 'html-loader'
            },
            {
              exclude: /\.(js|css|less|html|jpg|png|gif)/,
              loader: 'file-loader',
              options: {
                outputPath: 'media'
              }
            }
        ]
      }
    ]
  }
}

resolve

alias
const path = require('path') 
module.exports = {
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src'),
      '@/components':
       path.resolve(__dirname, '..', 'src/components'),
      '@/utils':
      path.resolve(__dirname, '..', 'src/utils'),
      '@/services':
      path.resolve(__dirname, '..', 'src/services'),
      '@/models': 
      path.resolve(__dirname, '..', 'src/models'),
      '@/pages':
      path.resolve(__dirname, '..', 'src/pages'),
    }
  }
}
extensions modules
module.exports = {
  resolve: {
    // 配置省略文件路径的后缀名
    extensions: ['.js','.json','.jsx','.css']
    // 告诉 webpack 解析模块去找那个目录
    modules: [
      resolve(__dirname, '../../node_modules'),
      'node_modules'
    ]
  }
}

plugins

module.exports = {
  plugins: [
    
  ]
}

externals

// 拒绝 jqery 被打包
module.exports = {
  externals: {
    jquery: 'jQuery'
  }, 
  plugins: [
     new webpack.ProvidePlugin({
      $: "jquery",
     }),
  ]
}

Optimization

splitChunks
// 将 node_modules 中代码打包进一个 chunk 
// 自动分析多入口 chunk 有没有公共文件 有的话会打包成单独一个 chunk
module.exports = {
  optimization: {
    splitChunks: {
      chunks: 'all async'
    },
  },
}

devtool

source-map
module.exports = {
  devtool: 'cheap-module-source-map'
}
#
source-map: 一种 提供源代码到构建后代码映射 技术 (如果构建后代码出错了,通过映射可以追踪源代码错误)
  
[inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map
  
      source-map:外部
        错误代码准确信息 和 源代码的错误位置
      inline-source-map:内联
        只生成一个内联source-map
        错误代码准确信息 和 源代码的错误位置
      hidden-source-map:外部
        错误代码错误原因,但是没有错误位置
        不能追踪源代码错误,只能提示到构建后代码的错误位置
      eval-source-map:内联
        每一个文件都生成对应的source-map,都在eval
        错误代码准确信息 和 源代码的错误位置
      nosources-source-map:外部
        错误代码准确信息, 但是没有任何源代码信息
      cheap-source-map:外部
        错误代码准确信息 和 源代码的错误位置 
        只能精确的行
      cheap-module-source-map:外部
        错误代码准确信息 和 源代码的错误位置 
        module会将loader的source map加入
  
    内联 和 外部的区别:1. 外部生成了文件,内联没有 2. 内联构建速度更快
  
      开发环境:速度快,调试更友好
        速度快(eval>inline>cheap>...)
          eval-cheap-souce-map
          eval-source-map
        调试更友好  
          souce-map
          cheap-module-souce-map
          cheap-souce-map
  
        --> eval-source-map  / eval-cheap-module-souce-map
  
      生产环境:源代码要不要隐藏? 调试要不要更友好
        内联会让代码体积变大,所以在生产环境不用内联
        nosources-source-map 全部隐藏
        hidden-source-map 只隐藏源代码,会提示构建后代码错误信息
  
        --> source-map / cheap-module-souce-map
                                    

4. demo

css抽离

plugins: [
   new MiniCssExtractPlugin({
     // 对输出的css文件进行重命名
     filename: 'css/built.css'
   }),
   // 压缩css
   new OptimizeCssAssetsWebpackPlugin()
]

#
  {
        test: /\.css$/,
        use: [ 'file-loader']
             ['file-loader?name=[name].bundle[hash].css']
  },

js抽离

 output: {
    filename: 'js/[name].js',
    path: path.resolve(__dirname, 'dist'),
  },

js语法检查

#
eslint eslint-loader
package.json 中添加
// 排除第三方库 只检查自己的代码
"eslintConfig": { "extends": "airbnb-base"}
#
module: {
  rules: [
    {
      test: /\.js$/,
      exclude: /node_modules/,
      loader: 'eslint-loader',
      options: {
            // 自动修复eslint的错误
        fix: true
      }
    }
  ]
}

代码切割

1. 多入口 自动打包多个文件
   entry: {
    'jquery': './src/index.js',
    'angular': './src/2.js'
  },
2. 异部的chunk
   require.ensure([],function(_require){
     _require('./xxx')
   })
  import('./2.css').then(() => {
    ...
  })
}
# 
3. 
optimization: {
  splitChunks: {
    chunks: 'all'
  }
}
#
externals: {
  jquery: 'jQuery'
}
cdn

dll

#
硬链接一个 包,再手动scrit引入这个包 之后webpack就不用编译了
#
yarn add add-asset-html-webpack-plugin
webpack --config webpack.config.dll.js && webpack
# 文件路径
  webpack.config.js
  webpack.config.dll.js
  dist
     index.html    
  src
  public
  dll
     jquery
     manifest.json
# webpack.config.js
const path = require('path')
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');
module.export = {
  ...
  externals: {
    jquery: 'jQuery'
  },
  plugins:[
    new HtmlWebpackPlugin({
      template: './index.html',
      filename: 'index.html',
      minify: { removeComments: true }
    }),
    // 告诉webpack哪些库不参与打包,同时使用时的名称也得变~
    new webpack.DllReferencePlugin({
        manifest: resolve(__dirname, 'dll/manifest.json')
    }),
    // 将某个文件打包输出去,并在html中自动引入该资源
    new AddAssetHtmlPlugin({
       filepath: path.resolve(__dirname, 'dll/jquery.js'),
       publicPath: '../dll',
       outputPath: 'vendor',
    }),
  ]
}
# webpack.config.dll.js
const path = require('path');
const webpack = require('webpack')
module.exports = {
  entry: {
    jquery: ['jquery'],
  },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'dll'),
    library: '[name]_[hash]'
  },
  plugins: [
    // 打包生成一个 manifest.json --> 提供和jquery映射
    new webpack.DllPlugin({
      // 映射库的暴露的内容名称 和 library 相同
      name: '[name]_[hash]',
      path: path.join(__dirname, 'dll/manifest.json'),
    })
  ],
  mode: 'production'
};
externals: {
    jquery: 'jQuery'
},
new webpack.ProvidePlugin({
   $: path.resolve(path.join(__dirname, 'dll/jquery.js'))
}),
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值