# webapck_dome **Repository Path**: Xbaiss/webapck_dome ## Basic Information - **Project Name**: webapck_dome - **Description**: webapck4 打包js、 css、HTML,还有一些配置。以及mock.js - **Primary Language**: JavaScript - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-01-15 - **Last Updated**: 2021-01-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # webapck_dome #### 介绍 webapck4 打包js、 css、HTML #### 项目创建 网上材料 【https://blog.csdn.net/gao_xu_520/article/details/78049369】 1. 创建项目 ①进入项目目录 ②执行命令npm init ③一路都enter直到yes 2. 项目中安装 Webpack npm install webpack --save-dev 3. 构建自己的项目 在根目录下创建文件 dist -- 打包后的文件 src --需要打包的文件 webpack.config.js 配置 4. 编写js,配置webpack.config.js # 语法 ## Entry Entry 类型可以是以下三种中的一种 或者 相互组合: 类型 例子 含义 string './app/entry' 入口模块的文件路径,可以是相对路径。 array ['./app/entry1', './app/entry2'] 入口模块的文件路径,可以是相对路径。 object { a: './app/entry-a', b: ['./app/entry-b1', './app/entry-b2']} 配置多个入口,每个入口生成一个 Chunk 如果是 array 类型,则搭配 output.library 配置项使用时,只有数组里的最后一个入口文件的模块会被导出。 ## 兼容性 es6 使用babel处理es6 1.安装最新版本的babel cnpm i babel-loader @babel/code @babel/preset-env @babel/plugin-transform-runtime @babel/plugin-syntax-dynamic-import -D cnpm i -S @babel/runtime -D:--save-dev 简写,安装在devDependencies 里,devDependencies开发环境有效 babel 这些 只要转译一下就好,所以不需要再生产环境 去干嘛 ,所以只要安装在 开发环境就好 -S:--save简写,安装在dependencies里, dependencies这里的作用是 开发和生产环境都有效 2. 配置规则webpack.config.js module: { rules: [ // babel-loader 处理 jsx/js 文件,除了node_modules { test:/\.(jsx|js)$/, use:{ loader:'babel-loader' }, exclude:/node_modules/ } ] }, 3. 配置babel.config.js module.exports = { //@babel/presets-env 这是es6转成es5之间的规则,所以这个是告诉es6 按照什么规则转成es5 "presets": ["@babel/preset-env"], "plugins": [ //es6 有很多新增内置对象(比如set,map),runtime 就是处理这些内置对象 "@babel/plugin-transform-runtime", //用以解析识别import()动态导入语法---并非转换,而是解析识别 "@babel/plugin-syntax-dynamic-import" ] } ## css处理 css:npm install -D css-loader style-loader sass:npm install -D node-sass sass-loader less:npm install -D less less-loader postcss:自动添加前缀,css模块化等 npm install -D postcss-loader npm install -D autoprefixer(添加css3 前缀) 配置webpack.config.js module: { rules: [ { test:/\.(css|scss|sass)$/, use:[ 'style-loader', 'css-loader', 'postcss-loader', 'sass-loader' ] }, { test:/\.less$/, use:[ 'style-loader', 'css-loader', 'postcss-loader', 'less-loader' ] } ] }, 配置postcss.config.js(使用postcss-loader时就需要创建这个文件) module.exports = { plugins: [ //字段添加css3浏览器前缀 require('autoprefixer') ] }; ## 环境变量 在package.json 创建环境变量,然后在webpack.config.js 里使用,或者 开发中js 需要使用环境变量 如:package.json 设置 "scripts": { "bulid": "cross-env ENV_MODE=production mock=1 webpack --mode development", }, 在webpack.config.js使用 const ENV_NOME = procsee.env.ENV_NODE console.log(ENV_NODE)//执行npm run bulid 时, node 控制台 输出production console.log(procsee.env.mock)//执行npm run bulid 时,node 控制台 输出1 但是 这样index.js 是得不到这个值,需要使用webpack.DefinePlugin plugins: [ new webpack.DefinePlugin({ "ENV_MOCK":process.env.MOCK }) ] 这时 index.js console.log(ENV_MOCK)//浏览器会输出 1 ## 错误调试 在webpack.config.js配置devtool [https://www.webpackjs.com/configuration/devtool/] 开发环境: devtool:'cheap-module-eval-source-map' 生成环境: devtool:'cheap-module-source-map' ## 清理dist文件 clean-webpack-plugin 每次构建前清理dist文件(不是把dist 文件都清空,而是删除打包的那个文件) npm i clean-webpack-plugin --save-dev 在webpack.config.js配置 const { CleanWebpackPlugin} = require('clean-webpack-plugin'); plugins:[ new CleanWebpackPlugin() ] ## 设置别名 resolve【https://segmentfault.com/a/1190000013176083?utm_source=tag-newest】 module.exports = { resolve: { //别名 alias: { '@': path.resolve(__dirname, 'src') }, //省略后缀 extensions: ['.js', '.css', '.scss', '.less'] } } ## css模块化 【https://cloud.tencent.com/developer/article/1036799,https://blog.csdn.net/chdyiboke/article/details/79902796】 webpack.config.js { loader: 'css-loader', options: { module: true,//开启模块化 localIdentName: '[path]-[name]-[local]-[hash:base64:6]' } } # 运行测试 ## webpack-dev-server webpack-dev-server 主要提供两个功能: 1.为静态文件提供web服务 2.热更新(自动刷新)和热替换(HMR) 热更新(自动刷新)指当修改文件代码时webpack会进行自动编译,浏览器更新,更新网页内容 热替换指运行时更新各种模块,即局部刷新,简单理解是修改代码,浏览器不用更新,局部会发生变化 适用场景:页面比较复杂,异步接口比较多,比如表单填写,填写到一半的时候,修改代码,这时候 热替换的话,前面填写的内容不会消失,不用重新填写 2.安装webpack-dev-server 命令为npm install --save-dev webpack-dev-server ### 热更新 3.配置webpack.config.js文件 DevServer 是webpack开发服务器 devServer: { // 设置服务器访问的基本目录 contentBase: path.join(__dirname, "dome"), //设置服务端压缩 compress: true, //服务器的ip地址 域名 host: "localhost", //直接启动 open: true, //设置端口 默认是8080 port: 9000 }, 4.配置package.json文件 "scripts": { "dev": "webpack-dev-server --mode development" }, 5.dome 文件 创建index.html 注意 打包的js ### 热替换(HMR) 1. 在devServer里添加hot:true//开启热替换(HMR) 配置webpack.config.js文件 output: { //热替换(HMR)开启 会与chunkhash,contenthash冲突 ,所以只能用hash filename: "[name].[hash:7].js", ... }, devServer: { // 设置服务器访问的基本目录 contentBase: path.join(__dirname, "dome"), //设置服务端压缩 compress: true, //服务器的ip地址 域名 host: "localhost", //直接启动 open: true, //设置端口 默认是8080 port: 9000, hot:true//开启热替换(HMR) }, 引入插件webpack const webpack = require('webpack') plugins: [ //开启HMR () 建议:永远不要在生产环境( production )下启用 HMR new webpack.HotModuleReplacementPlugin(), //当开启HMR 的时候,适用该插件会显示模块的相对路径,建议用于开发环境 new webpack.NamedModulesPlugin() ] 注意:js 是不支持热替换的,需要以下操作 2. js 热替换 js模块 HRM 需要手动监听需要HMR的模块,当该模块额内容发生改变,会触发回调 A. 创建hmrtest.js export default function(){ console.log('热替换') } B. 在index.js import hmrtest from './hmrtest.js' if(module.hot){ module.hot.accept('./hmrtest.js',()=>{ //这里执行 写任何东西 ,这时实现热替换 hmrtest(); console.log('热替换 测试') }) } 注意:如果是脚手架创建项目,一般是不用这样,因为路由里面会有配置,不需要这样 3. 热替换(HMR)开启 会与chunkhash,contenthash冲突 filename 最好使用contenthash,这时候怎么办? 因为hash 每次都会生成一个新的值,这样不好, 解决方式: 【https://juejin.cn/post/6844903950156578824】 解决思路是,mode: "development" 开发环境使用hot ,生成环境不使用 (可以分别创建生成和开发的配置文件(生成 webpack.config.prod.js,开发webpack.config.dev.js,公共webpack.config.common.js)使用webapck-merge 去合并 如: 在webpack.config.prod.js 文件里: const merge = require("webapck-merge"); const commonConfig = require("./ebpack.config.common.js") const config={ mode:"production" } module.exports = merge(commonConfig,config); ) ### webpack-dev-server 在dist是不会生成文件,它构建的文件是在内存里 打包生成的文件是webapck ## npm run build 打包 打包js # 运行 打包 webpack -w ## 特殊情况的js 打包 1.暴露给全局变量window window.ylzMPS = ylzMPS; 因为webpack打包后,相当于ylzMPS对象在一个闭包中,只有暴露出来才能在外面调用到 2.webpack打包js 只要在目录下 执行webpack -w 也可以执行npm run build ## js 打包 filename: "test.[chunkhash].js", 时间戳 module.exports = { mode: "development", // JS 执行入口文件 entry: [ 'babel-polyfill', __dirname + '/src/js/YlzMPS.js', __dirname + '/src/js/YlzReadCard.js', ], output: { // 把所有依赖的模块合并输出到一个 bundle.js 文件 filename: "ylzDll.js", // 用于长效缓存 // 输出文件都放到 dist 目录下 path: path.join(__dirname, 'dist') }, module: { rules: [ ] }, plugins: [ ], }; 执行webpack -w ## css 打包成js 1. 安装css-loader style-loader 2. src 创建 admin.css body { color: #fff; background: #f00; } 3. src 创建 index.js import './admin.css'; import "./style.css" console.log('sss') 4. 配置 module.exports = { mode: "development", // JS 执行入口文件 entry: [ __dirname + '/src/css/index.js', ], output: { // 把所有依赖的模块合并输出到一个 bundle.js 文件 filename: "tests.js", // 用于长效缓存 // 输出文件都放到 dist 目录下 path: path.join(__dirname, 'demo') }, module: { rules: [ { test: /\.css$/, use: [ { loader: 'style-loader' }, { loader: 'css-loader', options: { modules: true } } ] } ] }, plugins: [ ], devServer: { contentBase: path.join(__dirname, "demo"),// 设置服务器访问的基本目录 compress: true, host: "localhost",//服务器的ip地址 open: true, port: 9000 } }; ## css打包成css文件 安装:npm install -D mini-css-extract-plugin const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { mode: "development", // JS 执行入口文件 entry: [ __dirname + '/src/css/index.js', ], output: { // 把所有依赖的模块合并输出到一个 bundle.js 文件 filename: "testss.js", // 用于长效缓存 // 输出文件都放到 dist 目录下 path: path.join(__dirname, 'demo') }, module: { rules: [ { test: /\.css$/, use: [ MiniCssExtractPlugin.loader, { loader: "css-loader" } ] }, { test: /\.less$/, use: [ MiniCssExtractPlugin.loader, { loader: "css-loader" }, { loader: "less-loader" } ] } ] }, plugins: [ new MiniCssExtractPlugin({ filename: "css/common.css" }), // 如果入口文件 是多个 entry: { index: './src/js/index.js', about: './src/js/about.js', }, // name 就是entry里面 index、about new MiniCssExtractPlugin({ filename: "css/[name].[contenthash:7].css", chunkFilename: 'css/[id].[chunkhash:7].css' }), ], devServer: { contentBase: path.join(__dirname, "demo"),// 设置服务器访问的基本目录 compress: true, host: "localhost",//服务器的ip地址 open: true, port: 9440 } }; //这边也要注意 mini-css-extract-plugin 与 热替换的冲突,但是后面的版本可能会支持, ## css 、js 打包文件的压缩 webapck 在mode 为production环境时打包js时有自动压缩js,但是css 没有,需要去配置 插件 安装: cnpm install -D babili-webpack-plugin optimize-css-assets-webpack-plugin babili-webpack-plugin 是基于babel压缩程序 压缩的是js optimize-css-assets-webpack-plugin是压缩css webpack.config.js配置 const BabiliPlugin = require("babili-webpack-plugin"); const OptimizeCss = require('optimize-css-assets-webpack-plugin'); module.exports = { ... //提取公共文件 optimization: { ... //提取manifest,管理模块之间的交互 runtimeChunk: { name: "mainfest" }, //压缩文件 minimizer: [ //这是一款基于babel的压缩工具,支持es6的一些特性,取代uglifyJS new BabiliPlugin(), //压缩css new OptimizeCss() ] } } 注意 本来有自动压缩js,但是如果配置minimizer的话,webapck就是走minimizer的配置 项压缩,配置啥就压缩啥 ## webpack 引入css 的问题 import "./style.css" 报错 正确 import 'style-loader!css-loader!./admin.css'; const path = require('path'); const webpack = require('webpack') const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { mode: "development", // JS 执行入口文件 entry: [ __dirname + '/src/css/index.js', ], output: { // 把所有依赖的模块合并输出到一个 bundle.js 文件 filename: "testss.js", // 用于长效缓存 // 输出文件都放到 dist 目录下 path: path.join(__dirname, 'demo') }, module: { rules: [ { test: /\.css$/, use: [ MiniCssExtractPlugin.loader, { loader: "css-loader" } ] }, { test: /\.less$/, use: [ MiniCssExtractPlugin.loader, { loader: "css-loader" }, { loader: "less-loader" } ] } ] }, plugins: [ new MiniCssExtractPlugin({ filename: "css/common.css" }), ], devServer: { contentBase: path.join(__dirname, "demo"),// 设置服务器访问的基本目录 compress: true, host: "localhost",//服务器的ip地址 open: true, port: 9440 } }; ## html 打包 src文件创建 index.html /about.html index.js/about.js webpack.config.js 配置 const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { mode: "development", // JS 执行入口文件 entry: { index: './src/js/index.js', about: './src/js/about.js', }, // 出口配置 output: { // 把所有依赖的模块合并输出到一个 bundle.js 文件 filename: "[name].[contenthash:7].js", // 用于长效缓存 //非入口chunk文件(比如动态加载的文件)名 chunkFilename: '[id].[chunkhash:7].js', // 输出文件都放到 dist 目录下 path: path.join(__dirname, 'dist') }, plugins: [ new HtmlWebpackPlugin({ template: './src/html/index.html', // 模板路径 要打包的文件 filename: 'home.html',//生成的文件名 // script 标签生成 ,位于哪个地方 // true 默认 body里, body :body里,head:head里, inject: true, // 静态资源带hash hash: true, // 对生成的HTML 文件进行压缩 minify: { //压缩HTML的js minifyJS: true, //压缩HTML的css minifyCSS: true, // 删除HTML的注释 removeComments: true, // 去除标签属性的引号 removeAttributeQuotes: false, // 删除空值属性 removeEmptyAttributes: true, //省略布尔值的属性值 collapseBooleanAttributes: true, // 移除type='text/JavaScript' 其他类型属性值保持不变 removeScriptTypeAttributes: true, // 移除type='text/css' 其他类型属性值保持不变 removeStyleLinkTypeAttributes: true, //不要在display:inline的元素之间留下任何空格 //必须与 collapseWhitespace 一起用 collapseInlineTagWhitespace: true, collapseWhitespace: true }, //主要用于多页面 ,当你有多个入口文件 // 那就会编译后生成多个打包后的文件 // 那么chunks 就你选择你要使用的哪些js文件 // 这些文件会自动添加到生的HTML中 // chunks: ['index'] }) ], }; ## 图片,字体等资源处理 npm install -D file-loader url-loader 1. 字体图标下载【https://www.iconfont.cn/search?q=home】 2. src/js/index.js import '../css/admin.css'; //字体图标 import "../iconfont/iconfont.css"; import fj from '../img/fj.jpg' 3. src/html/index.html 首页

字体图片


HTML直接引用

仓鼠

css引用

4. 处理直接HTML 中的引用图片 需要安装 npm install html-withimg-loader -S module: { rules: [ { test: /\.(htm|html)$/, use: [ 'html-withimg-loader' ] }, ] } //这样配置会报错 html-webpack-plugin could not minify the generated output. 需要在图片 url-loader 的时候配置esModule: false 5. 在css引用图片时 相对路径的话可能会,打包的出来的js文件,构建出来的图片可能跟HTML不在同一个路径。 如果css提取的话,那路径就跟HTML 的路径就不一样,所以需要配置 才用绝对路径,publicPath: "./" 6. webpack.config.js 配置: 没有提取css 时 const path = require('path'); const webpack = require('webpack') const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { mode: "development", // JS 执行入口文件 entry: { index: './src/js/index.js', about: './src/js/about.js', }, // 出口配置 output: { // 把所有依赖的模块合并输出到一个 bundle.js 文件 filename: "[name].[contenthash:7].js", // 用于长效缓存 //非入口chunk文件(比如动态加载的文件)名 chunkFilename: '[id].[chunkhash:7].js', // 输出文件都放到 dist 目录下 path: path.join(__dirname, 'dist') }, devServer: { // 设置服务器访问的基本目录 contentBase: path.join(__dirname, "dist"), //设置服务端压缩 compress: true, //服务器的ip地址 域名 host: "localhost", //直接启动 open: true, //设置端口 默认是8080 port: 9000 }, module: { rules: [ { test: /\.(jsx|js)$/, use: { loader: "babel-loader" }, exclude: /node-modules/ }, { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] }, { test: /\.(htm|html)$/, use: [ 'html-withimg-loader' ] }, { test: /\.(png|jpg|svg|gif)$/, use: [ { loader: 'url-loader', options: { limit: 10* 1024, //单位为bit 10k以内的图片转正base64打包到js中 name: '[name]-[contenthash:7].[ext]',//打包文件名 outputPath: 'images/',//打包路径 esModule: false } } ] }, { test: /\.(woff|woff2|eot|ttf|otf)$/, use: [ { loader: 'url-loader', options: { limit: 10 * 1024, //10k以内的文件转正base64打包到js中 // 如果是超过10k 的话,是打包在font的文件下 name: '[name]-[contenthash:7].[ext]',//打包文件名 outputPath: 'font/'//打包路径 } } ] } ] }, plugins: [ // 清理dist 文件 new CleanWebpackPlugin(), // HTML模块生成 new HtmlWebpackPlugin({ template: './src/html/index.html', // 模板路径 要打包的文件 filename: 'index.html',//生成的文件名 // script 标签生成 ,位于哪个地方 // true 默认 body里, body :body里,head:head里, inject: true, // 静态资源带hash hash: true, // 对生成的HTML 文件进行压缩 minify: { //压缩HTML的js minifyJS: true, //压缩HTML的css minifyCSS: true, // 删除HTML的注释 removeComments: true, // 去除标签属性的引号 removeAttributeQuotes: false, // 删除空值属性 removeEmptyAttributes: true, //省略布尔值的属性值 collapseBooleanAttributes: true, // 移除type='text/JavaScript' 其他类型属性值保持不变 removeScriptTypeAttributes: true, // 移除type='text/css' 其他类型属性值保持不变 removeStyleLinkTypeAttributes: true, //不要在display:inline的元素之间留下任何空格 //必须与 collapseWhitespace 一起用 collapseInlineTagWhitespace: true, collapseWhitespace: true }, //主要用于多页面 ,当你有多个入口文件 // 那就会编译后生成多个打包后的文件 // 那么chunks 就你选择你要使用的哪些js文件 // 这些文件会自动添加到生的HTML中 chunks: ['index'] }) ], }; 提取css,绝对路径 const path = require('path'); const webpack = require('webpack') const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin') const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { mode: "development", // JS 执行入口文件 entry: { index: './src/js/index.js', about: './src/js/about.js', }, // 出口配置 output: { // 把所有依赖的模块合并输出到一个 bundle.js 文件 filename: "[name].[contenthash:7].js", // 用于长效缓存 //非入口chunk文件(比如动态加载的文件)名 chunkFilename: '[id].[chunkhash:7].js', // 输出文件都放到 dist 目录下 path: path.join(__dirname, 'dist'), publicPath: "./" }, devServer: { // 设置服务器访问的基本目录 contentBase: path.join(__dirname, "dist"), //设置服务端压缩 compress: true, //服务器的ip地址 域名 host: "localhost", //直接启动 open: true, //设置端口 默认是8080 port: 9000 }, module: { rules: [ { test: /\.(jsx|js)$/, use: { loader: "babel-loader" }, exclude: /node-modules/ }, { test: /\.css$/, use: [ MiniCssExtractPlugin.loader, { loader: "css-loader" } ] }, { test: /\.(htm|html)$/, loader: 'html-withimg-loader' }, { test: /\.(png|jpg|svg|gif)$/, use: [ { loader: 'url-loader', options: { limit: 100 * 1024, //单位为bit 10k以内的图片转正base64打包到js中 name: '[name]-[contenthash:7].[ext]',//打包文件名 esModule: false, outputPath: 'images/'//打包路径 } } ] }, { test: /\.(woff|woff2|eot|ttf|otf)$/, use: [ { loader: 'url-loader', options: { limit: 1 * 1024, //10k以内的文件转正base64打包到js中 // 如果是超过10k 的话,是打包在font的文件下 name: '[name]-[contenthash:7].[ext]',//打包文件名 outputPath: 'font/'//打包路径 } } ] } ] }, plugins: [ // 清理dist 文件 new CleanWebpackPlugin(), // HTML模块生成 new HtmlWebpackPlugin({ template: './src/html/index.html', // 模板路径 要打包的文件 filename: 'index.html',//生成的文件名 // script 标签生成 ,位于哪个地方 // true 默认 body里, body :body里,head:head里, inject: true, // 静态资源带hash hash: true, // 对生成的HTML 文件进行压缩 minify: { //压缩HTML的js minifyJS: true, //压缩HTML的css minifyCSS: true, // 删除HTML的注释 removeComments: true, // 去除标签属性的引号 removeAttributeQuotes: false, // 删除空值属性 removeEmptyAttributes: true, //省略布尔值的属性值 collapseBooleanAttributes: true, // 移除type='text/JavaScript' 其他类型属性值保持不变 removeScriptTypeAttributes: true, // 移除type='text/css' 其他类型属性值保持不变 removeStyleLinkTypeAttributes: true, //不要在display:inline的元素之间留下任何空格 //必须与 collapseWhitespace 一起用 collapseInlineTagWhitespace: true, collapseWhitespace: true }, //主要用于多页面 ,当你有多个入口文件 // 那就会编译后生成多个打包后的文件 // 那么chunks 就你选择你要使用的哪些js文件 // 这些文件会自动添加到生的HTML中 chunks: ['index'] }), //css 提取 new MiniCssExtractPlugin({ filename: "css/[name].[hash:7].css", chunkFilename: 'css/[id].[hash:7].css' }) ], }; ## 打包公共的js,css,插件 从webpack4开始官方移除了commonchunk插件,改用了optimization【https://webpack.docschina.org/configuration/optimization/】属性进行更加灵活的配置 案例index.html,about.html 2个页面, 公共部分:在2个页面的js里都引用import test from './test.js' 的文件 引入插件:在index.js 引入axios插件 webapck.config.js配置 plugins: [ new HtmlWebpackPlugin({ template: './src/html/index.html', // 模板路径 要打包的文件 filename: 'index.html',//生成的文件名 ... chunks: ['styles', 'vendor', 'common', 'mainfest', 'index'] }) new HtmlWebpackPlugin({ template: './src/html/about.html', // 模板路径 要打包的文件 filename: 'about.html',//生成的文件名 ... chunks: ['styles', 'vendor', 'common', 'mainfest', 'about'] }) ], //提取公共文件 optimization: { //这个表示从哪些chunks里面抽取代码,"initial"(入口文件)|"all" (所有) splitChunks: { chunks: 'async', //限制抽取出来的文件在压缩前最小大小,默认30000 minSize: 30000, //限制抽取出来的文件在压缩前最大大小,默认0,表示不限制最大大小 maxSize: 0, // 表示被引用次数,默认1 minChunks: 1, //最大异步请求数,默认5 maxAsyncRequests: 5, //最大的初始化加载次数,默认3 maxInitialRequests: 3, //抽取出来的文件的自动生成名字的分隔符,默认为~ automaticNameDelimiter: '~', // 抽取出来的文件名字,默认为true,表示自动生成文件名 name: false, // 上面的那么多参数其实都可以不用管, // cacheGroups才是关键,它可以继承、覆盖上面splitChunks中所有的参数值 // 设置缓存组用来抽取满足不同规则的chunk cacheGroups: { //将所有css 文件打包成一个 // 注意将权重设置为最高,不然可能其他的cacheGroups会提前打包一部分样式文件 // priority表示抽取权重,数字越大表示优先级越高,因为一个module可能会满足多个cacheGroups的条件 styles: { name: 'styles', test: /\.(scss|css|sass|less)$/, chunks: 'all', //如果cacheGroups中没有设置minsize,则据此判断是否使用上层的minsize // true 则是使用0, 0表示不限制大小 // false 使用上层minsize enforce: true, priority: 20 }, // 第三方库单独打包 vendor: { name: 'vendor', chunks: 'initial', priority: 10, test: /node_modules/, enforce: true, }, //把所有引入超过1次的模块抽取为cmmon common: { name: 'common', chunks: 'initial', priority: 2, minChunks: 2, enforce: true } } }, //提取manifest,管理模块之间的交互 runtimeChunk: { name: "mainfest" } } 完整的是: const path = require('path'); const webpack = require('webpack') const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin') const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const BabiliPlugin = require("babili-webpack-plugin"); const OptimizeCss = require('optimize-css-assets-webpack-plugin'); module.exports = { //设置环境 development / production mode: "production", // JS 执行入口文件 entry: { index: './src/js/index.js', about: './src/js/about.js', }, // 出口配置 output: { // 把所有依赖的模块合并输出到一个 bundle.js 文件 filename: "[name].[contenthash:7].js", // 用于长效缓存 //非入口chunk文件(比如动态加载的文件)名 chunkFilename: '[id].[chunkhash:7].js', // 输出文件都放到 dist 目录下 path: path.join(__dirname, 'dist'), publicPath: "./" }, devServer: { // 设置服务器访问的基本目录 contentBase: path.join(__dirname, "dist"), //设置服务端压缩 compress: true, //服务器的ip地址 域名 host: "localhost", //直接启动 open: true, //设置端口 默认是8080 port: 9000 }, module: { rules: [ { test: /\.(jsx|js)$/, use: { loader: "babel-loader" }, exclude: /node-modules/ }, { test: /\.css$/, use: [ MiniCssExtractPlugin.loader, { loader: "css-loader" } ] }, { test: /\.(htm|html)$/, loader: 'html-withimg-loader' }, { test: /\.(png|jpg|svg|gif)$/, use: [ { loader: 'url-loader', options: { limit: 100 * 1024, //单位为bit 10k以内的图片转正base64打包到js中 name: '[name]-[contenthash:7].[ext]',//打包文件名 esModule: false, outputPath: 'images/'//打包路径 } } ] }, { test: /\.(woff|woff2|eot|ttf|otf)$/, use: [ { loader: 'url-loader', options: { limit: 1 * 1024, //10k以内的文件转正base64打包到js中 // 如果是超过10k 的话,是打包在font的文件下 name: '[name]-[contenthash:7].[ext]',//打包文件名 outputPath: 'font/'//打包路径 } } ] } ] }, plugins: [ // 清理dist 文件 new CleanWebpackPlugin(), //css 提取 new MiniCssExtractPlugin({ filename: "css/[name].[hash:7].css", chunkFilename: 'css/[name].[hash:7].css' }), // HTML模块生成 new HtmlWebpackPlugin({ template: './src/html/index.html', // 模板路径 要打包的文件 filename: 'index.html',//生成的文件名 // script 标签生成 ,位于哪个地方 // true 默认 body里, body :body里,head:head里, inject: true, // 静态资源带hash hash: true, // 对生成的HTML 文件进行压缩 minify: { //压缩HTML的js minifyJS: true, //压缩HTML的css minifyCSS: true, // 删除HTML的注释 removeComments: true, // 去除标签属性的引号 removeAttributeQuotes: false, // 删除空值属性 removeEmptyAttributes: true, //省略布尔值的属性值 collapseBooleanAttributes: true, // 移除type='text/JavaScript' 其他类型属性值保持不变 removeScriptTypeAttributes: true, // 移除type='text/css' 其他类型属性值保持不变 removeStyleLinkTypeAttributes: true, //不要在display:inline的元素之间留下任何空格 //必须与 collapseWhitespace 一起用 collapseInlineTagWhitespace: true, collapseWhitespace: true }, //主要用于多页面 ,当你有多个入口文件 // 那就会编译后生成多个打包后的文件 // 那么chunks 就你选择你要使用的哪些js文件 // 这些文件会自动添加到生的HTML中 chunks: ['styles', 'vendor', 'common', 'mainfest', 'index'] }), new HtmlWebpackPlugin({ template: './src/html/about.html', // 模板路径 要打包的文件 filename: 'about.html',//生成的文件名 // script 标签生成 ,位于哪个地方 // true 默认 body里, body :body里,head:head里, inject: true, // 静态资源带hash hash: true, // 对生成的HTML 文件进行压缩 minify: { //压缩HTML的js minifyJS: true, //压缩HTML的css minifyCSS: true, // 删除HTML的注释 removeComments: true, // 去除标签属性的引号 removeAttributeQuotes: false, // 删除空值属性 removeEmptyAttributes: true, //省略布尔值的属性值 collapseBooleanAttributes: true, // 移除type='text/JavaScript' 其他类型属性值保持不变 removeScriptTypeAttributes: true, // 移除type='text/css' 其他类型属性值保持不变 removeStyleLinkTypeAttributes: true, //不要在display:inline的元素之间留下任何空格 //必须与 collapseWhitespace 一起用 collapseInlineTagWhitespace: true, collapseWhitespace: true }, //主要用于多页面 ,当你有多个入口文件 // 那就会编译后生成多个打包后的文件 // 那么chunks 就你选择你要使用的哪些js文件 // 这些文件会自动添加到生的HTML中 chunks: ['styles', 'vendor', 'common', 'mainfest', 'about'] }) ], //提取公共文件 optimization: { //这个表示从哪些chunks里面抽取代码,"initial"(入口文件)|"all" (所有) splitChunks: { chunks: 'async', //限制抽取出来的文件在压缩前最小大小,默认30000 minSize: 30000, //限制抽取出来的文件在压缩前最大大小,默认0,表示不限制最大大小 maxSize: 0, // 表示被引用次数,默认1 minChunks: 1, //最大异步请求数,默认5 maxAsyncRequests: 5, //最大的初始化加载次数,默认3 maxInitialRequests: 3, //抽取出来的文件的自动生成名字的分隔符,默认为~ automaticNameDelimiter: '~', // 抽取出来的文件名字,默认为true,表示自动生成文件名 name: false, // 上面的那么多参数其实都可以不用管, // cacheGroups才是关键,它可以继承、覆盖上面splitChunks中所有的参数值 // 设置缓存组用来抽取满足不同规则的chunk cacheGroups: { //将所有css 文件打包成一个 // 注意将权重设置为最高,不然可能其他的cacheGroups会提前打包一部分样式文件 // priority表示抽取权重,数字越大表示优先级越高,因为一个module可能会满足多个cacheGroups的条件 styles: { name: 'styles', test: /\.(scss|css|sass|less)$/, chunks: 'all', //如果cacheGroups中没有设置minsize,则据此判断是否使用上层的minsize // true 则是使用0, 0表示不限制大小 // false 使用上层minsize enforce: true, priority: 20 }, // 第三方库单独打包 vendor: { name: 'vendor', chunks: 'initial', priority: 10, test: /node_modules/, enforce: true, }, //把所有引入超过1次的模块抽取为cmmon common: { name: 'common', chunks: 'initial', priority: 2, minChunks: 2, enforce: true } } }, //提取manifest,管理模块之间的交互 runtimeChunk: { name: "mainfest" }, //压缩文件 minimizer: [ //这是一款基于babel的压缩工具,支持es6的一些特性,取代uglifyJS new BabiliPlugin(), //压缩css new OptimizeCss() ] } }; 执行 npm run build dist就会生成 common.2.js,vendor.f.js,mainfest.6.js,styles.2.js .index.js/about.js ## 不想处理的资源 的打包操作 比如pubilc 的文件不想处理,只要打包就好, 安装loader:cnpm i -D copy-webpack-plugin@6.3.1 webpack.config.js配置 const CopyWebpackPlugin = require("copy-webpack-plugin") module.exports = { plugins: [ // 复制插件 new CopyWebpackPlugin( { patterns: [{ from: path.join(__dirname, '/src/pubilc'), to: 'pubilc' }] } // 需要拷贝的目录或者路径通配符 ) ], }; 这时就把src 中pubilc 复制到 dist 里 # mock 工程化 # 遇到的错误问题 1. Unknown option: .plugin. Check out https://babeljs.io/docs/en/babel-core/#options for more information about options. 问题是:资源没加载到,可以查看配置比如:babel.config.js的plugin配置或是babelrc的plugin配置 2. 使用mini-css-extract-plugin 报错ReferenceError: document is not defined 因为style-loader和 mini-css-extract-plugin 冲突,去除掉style-loader即可 3. copy-webpack-plugin 版本问题,或是 解决问题ValidationError: CopyPlugin Invalid Options node 版本 v12.13.0 安装"copy-webpack-plugin": "^6.3.1", 就可以解决