在网上找做设计是什么网站,番禺做网站多少钱,参考消息电子版报纸,营销活动有哪些3.1 打包样式资源css-loader、style-loader… {// 匹配哪些文件test: /\.less$/,// 使用哪些loader进行处理use: [// use数组中loader执行顺序#xff1a;从右到左#xff0c;从下到上#xff0c;依次执行(先执行css-loader)// style-loader#xff1a;创建style标签#…3.1 打包样式资源css-loader、style-loader… {// 匹配哪些文件test: /\.less$/,// 使用哪些loader进行处理use: [// use数组中loader执行顺序从右到左从下到上依次执行(先执行css-loader)// style-loader创建style标签将js中的样式资源插入进去添加到head中生效style-loader,// css-loader将css文件变成commonjs模块加载到js中里面内容是样式字符串css-loader,// less-loader将less文件编译成css文件需要下载less-loader和lessless-loader],},{test: /\.css$/,//使用多个loader用use,使用一个loader用loaderuse: [style-loader, css-loader],},
3.2 打包 html 资源HtmlWebpackPlugin // plugin的配置plugins: [// html-webpack-plugin默认会创建一个空的html文件自动引入打包输出的所有资源JS/CSS// 需要有结构的HTML文件可以加一个templatenew HtmlWebpackPlugin({// 复制这个./src/index.html文件并自动引入打包输出的所有资源JS/CSStemplate: ./src/index.html,}),],
3.3 打包图片资源url-loader、html-loader
url-loader处理图片资源问题默认处理不了html中的img图片,只能处理css中的图片使用url-loader需要下载file-loaderurl依赖于file-loader图片大小小于8kb就会被base64处理 优点减少请求数量减轻服务器压力 缺点图片体积会更大文件请求速度更慢base64在客户端本地解码所以会减少服务器压力如果图片过大还采用base64编码会导致cpu调用率上升网页加载时变卡问题这里使用html-loader处理html文件的img图片时会出现一个问题因为url-loader默认使用es6模块化解析而html-loader引入图片是conmonjs解析时会出问题[object Module] 解决关闭url-loader的es6模块化使用commonjs解析当webpack在解析的时候发现我们引入的是同一张图片,他不会重复打包,只会输入一次 {// url-loader处理图片资源问题默认处理不了html中的img图片test: /\.(jpg|png|gif)$/,// 需要下载 url-loader file-loader两个包loader: url-loader,//使用多个loader用use,使用一个loader用loaderoptions: {limit: 8 \* 1024,// 给图片重命名[hash:10]取图片的hash的前10位[ext]取文件原来扩展名name: [hash:10].[ext],// 问题因为url-loader默认使用es6模块化解析而html-loader引入图片是conmonjs解析时会出问题[object Module]// 解决关闭url-loader的es6模块化使用commonjs解析esModule: false,outputPath: imgs},},//当webpack在解析的时候发现我们引入的是同一张图片,他不会重复打包,只会输入一次// 处理html文件的img图片{test: /\.html$/,// 处理html文件的img图片负责引入img从而能被url-loader进行处理loader: html-loader,//需要下载html-loader包 },
3.4 打包其他资源file-loader
url-loader和file-loader的区别:
url-loader可以压缩图片,转换为base64file-loader原封不动的将文件输出 // 打包其他资源(除了html/js/css资源以外的资源) 比如字体图标{// 排除html|js|css|less|jpg|png|gif文件exclude: /\.(html|js|css|less|jpg|png|gif)/,// file-loader处理其他文件loader: file-loader,options: {name: [hash:10].[ext],outputPath: media,},},
3.5 devServer 开发服务器
用来自动化自动编译自动打开浏览器自动刷新浏览器 特点只会在内存中编译打包不会有任何输出 需要下载包webpack-dev-server 启动derServer指令为 npx webpack-dev-server
devServer: {contentBase: resolve(__dirname, build),//项目构建后路径compress: true,//启动gzip压缩port: 3000,//端口号open: true,//自动打开浏览器// 开启HMR功能// 当修改了webpack配置新配置要想生效必须重启webpack服务hot: true
}
下面是一个简单的开发环境webpack.confg.js配置文件
// resolve用来拼接绝对路径的方法
const { resolve } require(path)
const HtmlWebpackPlugin require(html-webpack-plugin) // 引用pluginmodule.exports {// webpack配置entry: ./src/js/index.js, // 入口起点output: {// 输出// 输出文件名filename: js/build.js,// \_\_dirname是nodejs的变量代表当前文件的目录绝对路径path: resolve(__dirname, build), // 输出路径所有资源打包都会输出到这个文件夹下},// loader配置module: {rules: [// 详细的loader配置// 不同文件必须配置不同loader处理{// 匹配哪些文件test: /\.less$/,// 使用哪些loader进行处理use: [// use数组中loader执行顺序从右到左从下到上依次执行(先执行css-loader)// style-loader创建style标签将js中的样式资源插入进去添加到head中生效style-loader,// css-loader将css文件变成commonjs模块加载到js中里面内容是样式字符串css-loader,// less-loader将less文件编译成css文件需要下载less-loader和lessless-loader],},{test: /\.css$/,//使用多个loader用use,使用一个loader用loaderuse: [style-loader, css-loader],},{// url-loader处理图片资源问题默认处理不了html中的img图片test: /\.(jpg|png|gif)$/,// 需要下载 url-loader file-loader两个包loader: url-loader,//使用多个loader用use,使用一个loader用loaderoptions: {// 图片大小小于8kb就会被base64处理优点减少请求数量减轻服务器压力缺点图片体积会更大文件请求速度更慢// base64在客户端本地解码所以会减少服务器压力如果图片过大还采用base64编码会导致cpu调用率上升网页加载时变卡limit: 8 \* 1024,// 给图片重命名[hash:10]取图片的hash的前10位[ext]取文件原来扩展名name: [hash:10].[ext],// 问题因为url-loader默认使用es6模块化解析而html-loader引入图片是conmonjs解析时会出问题[object Module]// 解决关闭url-loader的es6模块化使用commonjs解析esModule: false,outputPath: imgs//输出到imgs目录下},},//当webpack在解析的时候发现我们引入的是同一张图片,他不会重复打包,只会输入一次// 处理html文件的img图片{test: /\.html$/,// 处理html文件的img图片负责引入img从而能被url-loader进行处理loader: html-loader,//需要下载html-loader包 },//url-loader和file-loader的区别://url-loader可以压缩图片,转换为base64 //file-loader原封不动的将文件输入// 打包其他资源(除了html/js/css资源以外的资源) 比如字体图标{// 排除html|js|css|less|jpg|png|gif文件exclude: /\.(html|js|css|less|jpg|png|gif)/,// file-loader处理其他文件loader: file-loader,options: {name: [hash:10].[ext],outputPath: media,},},],},// plugin的配置plugins: [// html-webpack-plugin默认会创建一个空的html文件自动引入打包输出的所有资源JS/CSS// 需要有结构的HTML文件可以加一个templatenew HtmlWebpackPlugin({// 复制这个./src/index.html文件并自动引入打包输出的所有资源JS/CSStemplate: ./src/index.html,}),],// 模式mode: development, // 开发模式// 开发服务器 devServer用来自动化不用每次修改后都重新输入webpack打包一遍自动编译自动打开浏览器自动刷新浏览器// 特点只会在内存中编译打包不会有任何输出不会像之前那样在外面看到打包输出的build包而是在内存中关闭后会自动删除// 启动devServer指令为npx webpack-dev-serverdevServer: {// 项目构建后路径contentBase: resolve(__dirname, build),// 启动gzip压缩compress: true,// 端口号port: 3000,// 自动打开浏览器open: true,},
}
其中大部分配置都在注释中给出解释。
运行项目的两个指令
webpack 会将打包结果输出出去build文件夹
npx webpack-dev-server 只会在内存中编译打包没有输出
loader 和 plugin 的不同plugin 一定要先引入才能使用
loader1. 下载 2. 使用配置 loader
plugins1.下载 2. 引入 3. 使用
四、Webpack 生产环境的基本配置
而生产环境的配置需要考虑以下几个方面
1、提取 css 成单独文件mini-css-extract-plugin
css-loader将css文件整合到js文件中经过css-loader处理后样式文件是在js文件中的
问题1.js文件体积会很大 2.需要先加载js再动态创建style标签样式渲染速度就慢会出现闪屏现象
解决用MiniCssExtractPlugin.loader替代style-loader提取js中的css成单独文件然后通过link加载
const { resolve } require(path)
const MiniCssExtractorPlugin require(mini-css-extract-plugin)module.exports {entry: ./src/js/index.js,output: {filename: js/built.js,path: resolve(__dirname, build),},module: {rules: [{test: /\.css$/,use:[ //style-loader,//创建style标签,将样式放入//这个loader取代style-loader 作用:提取js中的css成单独文件MiniCssExtractorPlugin.loader,css-loader//将css文件整合到js文件中],}],},plugins: [new MiniCssExtractPlugin({// 对输出的css文件进行重命名filename: css/built.css,}),new HtmlWebpackPlugin({template: ./src/index.html}),],// 生产环境下会自动压缩js代码mode: production}
2、css 兼容性处理 postcss-loader
使用postcss-loadercss兼容性处理postcss -- 需要安装postcss-loader 和插件postcss-preset-env
有两种配置方法:
使用loader的默认配置postcss-loader ,这个在css-loader同级写postcss-loader修改loader的配置会使用到postcss-preset-env这个插件它主要作用就是postcss会以这个插件的形式做一些兼容性处理 postcss需要通过package.json中browserslist里面的配置加载指定的css兼容性样式 在package.json中定义browserslist
browserslist: {// 开发环境 -- 设置node环境变量process.env.NODE\_ENV developmentdevelopment: [ // 只需要可以运行即可last 1 chrome version,last 1 firefox version,last 1 safari version],// 生产环境。默认是生产环境production: [ // 需要满足绝大多数浏览器的兼容0.2%,not dead,not op\_mini all]},
默认是生产环境 , 这时候我们需要把nodejs环境变量设置为开发环境 , 开发环境主要是验证一些最近的浏览器的兼容性 这时候我们就可以看到打包的built.css里面的样式就会做一些兼容性处理了 如果我们将设置开发环境变量注释,那么我们会看到在生产环境端也是做了一些不同的兼容性处理
3、压缩 css optimizi-css-assets-webpack-plugin
安装optimizi-css-assets-webpack-plugin 压缩css非常简单只需要配置一个插件即可
const OptimiziCssAssetsWebpackPlugin require(optimizi-css-assets-webpack-plugin)
...plugins: [// 压缩cssnew OptimiziCssAssetsWebpackPlugin(),],
4、js 语法检查eslint-loader 、eslint
js的语法检查 需要下载 eslint-loader 和eslint
注意只检查自己写的源代码第三方的库是不用检查的
airbnb(一个流行的js风格) -- 需要下载 eslint-config-airbnb-base(这个库没有react的语法检查如果需要react可用eslint-config-airbnb 和eslint、 eslint-plugin-import
{test: /\.js$/,exclude: /node\_modules/, // 忽略node\_modulesenforce: pre, // 优先执行loader: eslint-loader,options: {// 自动修复fix: true,},
},
设置检查规则 package.json中eslintConfig中设置
eslintConfig: {extends: airbnb-base // 继承airbnb的风格规范env: {browser: true // 可以使用浏览器中的全局变量(使用window不会报错)}}
5、js 兼容性处理
js兼容性处理需要下载 babel-loader 、·babel/core、babel/preset-env、babel/polyfill
1. 基本js兼容性处理 -- babel/preset-env
问题只能转换基本语法如promise高级语法不能转换
2. 全部js兼容性处理 -- babel/polyfill(这个包不是插件只需要引入就可以使用了
问题只要解决部分兼容性问题但是将所有兼容性代码全部引入体积太大了
3. 需要做兼容性处理的就做按需加载 --core-js
使用这种方案的话我们就不能使用第二种方案了
{// 第三种方式按需加载test: /\.js$/,exclude: /node\_modules/,loader: babel-loader,options: {// 预设指示babel做怎样的兼容性处理presets: [babel/preset-env, // 基本预设{useBuiltIns: usage, //按需加载corejs: { version: 3 }, // 指定core-js版本targets: { // 指定兼容到什么版本的浏览器chrome: 60,firefox: 50,ie: 9,safari: 10,edge: 17},},],},
},
6、js 压缩
生产环境会自动压缩js代码
7、html 压缩
html不需要做兼容性处理只需要做压缩 new HtmlWebpackPlugin({template: ./src/index.html,// 压缩html代码minify: {// 移除空格collapseWhitespace: true,// 移除注释removeComments: true,},}),
下面是一个基本的生产环境下的webpack.config.js配置
正常来讲一个文件只能被一个loader处理当一个文件要被多个loader处理那么一定要指定loader执行的先后顺序 使用enforce优先执行
const { resolve } require(path)
const MiniCssExtractorPlugin require(mini-css-extract-plugin)
const OptimiziCssAssetsWebpackPlugin require(optimizi-css-assets-webpack-plugin)
const HtmlWebpackPlugin require(html-webpack-plugin)// 定义node.js的环境变量决定使用browserslist的哪个环境
process.env.NODE\_ENV production// 复用loader的写法
const commonCssLoader [// 这个loader取代style-loader。作用提取js中的css成单独文件然后通过link加载MiniCssExtractPlugin.loader,css-loader,/\*postcss需要通过package.json中browserslist里面的配置加载指定的css兼容性样式在package.json中定义browserslist见上面css兼容性处理的代码\*/{loader: postcss-loader,options: {ident: postcss, // 基本写法plugins: () [// postcss的插件require(postcss-preset-env)(),],},},
]module.exports {entry: ./src/js/index.js,output: {filename: js/built.js,path: resolve(__dirname, build),},module: {rules: [{test: /\.css$/,use: [...commonCssLoader],},{test: /\.less$/,use: [...commonCssLoader, less-loader], //commonCssLoader一定要写到less-loader上面因为它只能处理css文件less-loader把less转换为css之后使用},/\*正常来讲一个文件只能被一个loader处理当一个文件要被多个loader处理那么一定要指定loader执行的先后顺序先执行eslint再执行babel用enforce\*/{//设置检查规则 package.json中eslintConfig中设置见上面js语法检查设置规则test: /\.js$/,exclude: /node\_modules/, // 忽略node\_modulesenforce: pre, // 优先执行loader: eslint-loader,options: {// 自动修复fix: true,},},{// js兼容性处理第三种方式按需加载test: /\.js$/,exclude: /node\_modules/,loader: babel-loader,options: {// 预设指示babel做怎样的兼容性处理presets: [babel/preset-env, // 基本预设{useBuiltIns: usage, //按需加载corejs: { version: 3 }, // 指定core-js版本targets: { // 指定兼容到什么版本的浏览器chrome: 60,firefox: 50,ie: 9,safari: 10,edge: 17},},],},},{// 图片处理test: /\.(jpg|png|gif)/,loader: url-loader,options: {limit: 8 \* 1024,name: [hash:10].[ext],outputPath: imgs,esModule: false, // 关闭url-loader默认使用的es6模块化解析},},// html中的图片处理{test: /\.html$/,loader: html-loader,},// 处理其他文件{exclude: /\.(js|css|less|html|jpg|png|gif)/,loader: file-loader,options: {outputPath: media,},},],},plugins: [new MiniCssExtractPlugin({// 对输出的css文件进行重命名filename: css/built.css,}),// 压缩cssnew OptimiziCssAssetsWebpackPlugin(),// HtmlWebpackPluginhtml文件的打包和压缩处理// 通过这个插件会自动将单独打包的样式文件通过link标签引入new HtmlWebpackPlugin({template: ./src/index.html,// 压缩html代码minify: {// 移除空格collapseWhitespace: true,// 移除注释removeComments: true,},}),],// 生产环境下会自动压缩js代码mode: production,devServer: {contentBase: resolve(__dirname, build),compress: true,port: 3000,open: true,// 开启HMR功能// 当修改了webpack配置新配置要想生效必须重启webpack服务hot: true
}
}
五、Webpack 优化配置
5.1 开发环境性能优化
开发环境指令通过npx webpack-dev-server启动如果直接运行webpack是会直接打包看不到实时调试的效果
5.1.1 HMR模块热替换 优化打包构建速度
HMR: hot module replacement 热模块替换 / 模块热替换基于devServer只能在开发环境使用
作用一个模块发生变化只会重新打包构建这一个模块而不是打包所有模块 极大提升构建速度
代码只需要在 devServer 中设置 hot 为 true就会自动开启HMR功能只能在开发模式下使用
devServer: {contentBase: resolve(__dirname, build),compress: true,port: 3000,open: true,// 开启HMR功能// 当修改了webpack配置新配置要想生效必须重启webpack服务hot: true
}
每种文件实现热模块替换的情况
样式文件可以使用HMR功能因为开发环境下使用的style-loader 内部默认实现了热模块替换功能js 文件默认不能使用HMR功能修改一个 js 模块所有 js 模块都会刷新
解决实现 HMR 需要修改 js 代码添加支持 HMR 功能的代码
注意
1. HMR 功能对 js 的处理只能处理非入口 js 文件的其他文件因为入口文件会将其他文件引入一旦入口文件变化其他文件又会重新引入重新加载所以入口文件做不了HMR功能
2. 如果有多个js文件则需要写多个这样的函数// 绑定
if (module.hot) {// 一旦 module.hot 为true说明开启了HMR功能。 -- 让HMR功能代码生效module.hot.accept(./print.js, function() {// 方法会监听 print.js 文件的变化一旦发生变化只有这个模块会重新打包构建其他模块不会。// 会执行后面的回调函数print();});
}html 文件: 默认不能使用 HMR 功能同时会导致问题html文件不能热更新了不会自动打包构建html 不用做 HMR 功能如果是针对单文件组件的话因为只有一个 html 文件不需要再优化
解决修改 entry 入口将 html 文件引入这样 html 修改整体又会重新刷新
entry: [./src/js/index.js, ./src/index.html]
5.1.2 source-map 优化代码调式
source-map一种提供源代码到构建后代码的映射的技术 如果构建后代码出错了通过映射可以追踪源代码错误
参数[inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map
代码
devServer: {...
},
devtool: source-map
可选方案[生成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完整度高内联速度快 vue和react脚手架默认配置的就是这个 / eval-cheap-module-souce-map错误提示忽略列但是包含其他信息内联速度快
生产环境 需要考虑源代码要不要隐藏调试要不要更友好
内联会让代码体积变大所以在生产环境不用内联隐藏源代码 nosources-source-map 全部隐藏 hidden-source-map 只隐藏源代码会提示构建后代码错误信息 最终得出最 好的两种方案 -- source-map最完整 / cheap-module-souce-map错误提示一整行忽略列
5.2 生产环境性能优化
5.2.1 优化打包构建速度
1、 oneOf 匹配到 loader 后就不再向后进行匹配
oneOf匹配到 loader 后就不再向后进行匹配优化生产环境的打包构建速度
以下loader只会匹配一个匹配到了后就不会再往下匹配了注意不能有两个配置处理同一种类型文件所以把eslint-loader提取出去放外面
module: {rules: [{// js 语法检查test: /\.js$/,exclude: /node\_modules/,// 优先执行enforce: pre,loader: eslint-loader,options: {fix: true}},{// oneOf 优化生产环境的打包构建速度// 以下loader只会匹配一个匹配到了后就不会再往下匹配了// 注意不能有两个配置处理同一种类型文件所以把eslint-loader提取出去放外面oneOf: [{test: /\.css$/,use: [...commonCssLoader]},{test: /\.less$/,use: [...commonCssLoader, less-loader]},{// js 兼容性处理test: /\.js$/,exclude: /node\_modules/,loader: babel-loader,options: {presets: [[babel/preset-env,{useBuiltIns: usage,corejs: {version: 3},targets: {chrome: 60,firefox: 50}}]]}},{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}}]}]
},
2、 babel 缓存 cacheDirectory
类似 HMR将 babel 处理后的资源缓存起来哪里的js改变就更新哪里其他 js 还是用之前缓存的资源让第二次打包构建速度更快
{test: /\.js$/,exclude: /node\_modules/,loader: babel-loader,options: {presets: [[babel/preset-env,{useBuiltIns: usage,corejs: { version: 3 },targets: {chrome: 60,firefox: 50}}]],// 开启babel缓存// 第二次构建时会读取之前的缓存cacheDirectory: true}
},
3 、多进程打包 thread-loader
多进程打包某个任务消耗时间较长会卡顿多进程可以同一时间干多件事效率更高。
优点是提升打包速度缺点是每个进程的开启和交流都会有开销babel-loader消耗时间最久所以使用thread-loader 针对其进行优化
{test: /\.js$/,exclude: /node\_modules/,use: [/\* thread-loader会对其后面的loader这里是babel-loader开启多进程打包。 进程启动大概为600ms进程通信也有开销。(启动的开销比较昂贵不要滥用)只有工作消耗时间比较长才需要多进程打包\*/{loader: thread-loader,options: {workers: 2 // 进程2个}}, {loader: babel-loader,options: {presets: [[babel/preset-env,{useBuiltIns: usage,corejs: { version: 3 },targets: {chrome: 60,firefox: 50}}]],// 开启babel缓存// 第二次构建时会读取之前的缓存cacheDirectory: true}}]
},
4 、externals 让某些库不打包
externals让某些库不打包通过 cdn 引入
webpack.config.js 中配置
externals: {// 拒绝jQuery被打包进来(通过cdn引入速度会快一些)// 忽略的库名 -- npm包名jquery: jQuery
}
需要在 index.html 中通过 cdn 引入
script srchttps://cdn.bootcss.com/jquery/1.12.4/jquery.min.js/script
5 、dll 让某些库单独打包
dll让某些库单独打包后直接引入到 build 中优化了重复打包的性能 可以在 code split 分割出 node_modules 后再用 dll 更细的分割优化代码运行的性能。
node_modules的库会打包到一起但是很多库的时候打包输出的js文件就太大了使用dll技术对某些库第三方库jquery、react、vue…进行单独打包当运行webpack时默认查找webpack.config.js配置文件而我们通过dll打包之后需要运行webpack.dll.js文件这时候我们就需要修改webpack的指令 -- webpack --config webpack.dll.js运行这个指令表示以这个配置文件打包
webpack.dll.js 配置(将 jquery 单独打包) const { resolve } require(path);
const webpack require(webpack);module.exports {entry: {// 最终打包生成的[name] -- jquery// [jquery] -- 要打包的库是jqueryjquery: [jquery]//这里可以写很多很多库可以分别打包},output: {// 输出出口指定filename: [name].js, // name就是jquerypath: resolve(__dirname, dll), // 打包到dll目录下library: [name]\_[hash], // 打包的库里面向外暴露出去的内容叫什么名字},plugins: [// 打包生成一个manifest.json -- 提供jquery的映射关系告诉webpackjquery之后不需要再打包和暴露内容的名称new webpack.DllPlugin({name: [name]\_[hash], // 映射库的暴露的内容名称path: resolve(__dirname, dll/manifest.json) // 输出文件路径})],mode: production
};
webpack.config.js 配置(告诉 webpack 不需要再打包 jquery并将之前打包好的 jquery 跟其他打包好的资源一同输出到 build 目录下)
// 引入插件
const webpack require(webpack);
const AddAssetHtmlWebpackPlugin require(add-asset-html-webpack-plugin);// plugins中配置
plugins: [new HtmlWebpackPlugin({template: ./src/index.html}),// 告诉webpack哪些库不参与打包同时使用时的名称也得变new webpack.DllReferencePlugin({manifest: resolve(__dirname, dll/manifest.json)}),// 将某个文件打包输出到build目录下并在html中自动引入该资源new AddAssetHtmlWebpackPlugin({filepath: resolve(__dirname, dll/jquery.js)})
],
externals和dll的区别
externals彻底不打包需要通过cdn连接引进来dll需要打包一次不用重复打包可以结合代码分割按需拆分文件
5.2.2 优化代码运行的性能
1、文件资源缓存 hash-chunkhash-contenthash
文件名不变就不会重新请求而是再次用之前缓存的资源
hash: 每次 wepack 打包时会生成一个唯一的 hash 值。
问题重新打包所有文件的 hash 值都改变会导致所有缓存失效。比如只改动了一个js文件css文件也会被重新打包 原因因为js和css同时使用一个hash值 2. chunkhash根据 chunk 生成的 hash 值。来源于同一个 chunk的 hash 值一样
问题js 和 css 来自同一个chunkhash 值是一样的 原因因为 css-loader 会将 css 文件加载到 js 中所以同属于一个chunk
chunk概念比如一个入口文件引入了css文件、js文件形成了一个文件 这个文件就叫做一个chunk 3. contenthash: 根据文件的内容生成 hash 值。不同文件 hash 值一定不一样(文件内容修改文件名里的 hash 才会改变)
修改 css 文件内容打包后的 css 文件名 hash 值就改变而 js 文件没有改变 hash 值就不变这样 css 和 js 缓存就会分开判断要不要重新请求资源 -- 让代码上线运行缓存更好使用 打包结果不同文件hash值都不一样再次打包只要文件内容不变hash值就不会变化
2、tree shaking 去除无用代码
前提
必须使用 ES6 模块化开启 production 环境 这样就自动会把无用代码去掉
作用减少代码体积
在一些webpack版本中可能会摇掉一些css等的代码这时候我们需要在 package.json 中配置
sideEffects: false 表示所有代码都没有副作用都可以进行 tree shaking这样会导致的问题可能会把 css / babel/polyfill 文件干掉副作用
所以可以配置sideEffects: [*.css, *.less] 不会对css/less文件tree shaking处理
3、 code split代码分割
代码分割主要有两种场景单入口场景和多入口场景。
将打包输出的一个大的 bundle.js 文件拆分成多个小文件这样可以并行加载多个文件比加载一个文件更快。
比如我们在开发单页面应用的时候如vue整个页面是一个非常庞大的文件那么我们肯定要按照路由去拆分不同的文件从而实现按需加载这时候拆分文件就需要使用代码分割了
1多入口拆分
多入口有几个入口最终输出就有几个bundle 问题很难去维护多入口如果要修改多个页面总得去修改多入口
entry: {// 多入口有几个入口最终输出就有几个bundleindex: ./src/js/index.js,test: ./src/js/test.js},output: {// [name]取文件名filename: js/[name].[contenthash:10].js,path: resolve(__dirname, build)},
2optimization 将 node_modules中的代码单独打包
将 node_modules中的代码单独打包大小超过30kb自动分析多入口chunk中有没有公共的文件。如果有会打包成单独一个chunk(比如两个模块中都引入了jquery正常情况下多入口页面会打包两个引入jquery的文件使用optimization会被打包成一个单独的文件不会重复打包多次)大小超过30kb
optimization: {splitChunks: {chunks: all}},
3import 动态导入语法
通过js代码让某个文件被单独打包成一个chunk采用id命名0、1、2、3…避免命名冲突import动态导入语法能将某个文件单独打包(test文件不会和index打包在同一个文件而是单独打包)webpackChunkName:指定test单独打包后文件的名字 import(/\* webpackChunkName: test \*/./test).then(({ mul, count }) {// 文件加载成功~// eslint-disable-next-lineconsole.log(mul(2, 5));}).catch(() {// eslint-disable-next-lineconsole.log(文件加载失败~);});
4、 lazy loading懒加载/预加载
懒加载当文件需要使用时才加载需要代码分割。但是如果资源较大加载时间就会较长有延迟。正常加载可以认为是并行加载同一时间加载多个文件没有先后顺序先加载了不需要的资源就会浪费时间。预加载 prefetch兼容性很差会在使用之前提前加载。等其他资源加载完毕浏览器空闲了再偷偷加载这个资源。这样在使用时已经加载好了速度很快。所以在懒加载的基础上加上预加载会更好。
代码
document.getElementById(btn).onclick function() {// 将import的内容放在异步回调函数中使用点击按钮test.js才会被加载(不会重复加载)// webpackPrefetch: true表示开启预加载import(/\* webpackChunkName: test, webpackPrefetch: true \*/./test).then(({ mul }) {console.log(mul(4, 5));});import(./test).then(({ mul }) {console.log(mul(2, 5))})
};
5、pwa离线可访问技术
pwa离线可访问技术渐进式网络开发应用程序使用serviceworker和 workbox 技术。
优点是离线也能访问缺点是兼容性差。
webpack.config.js 中配置
const WorkboxWebpackPlugin require(workbox-webpack-plugin); // 引入插件// plugins中加入
new WorkboxWebpackPlugin.GenerateSW({/\*1. 帮助serviceworker快速启动2. 删除旧的 serviceworker生成一个 serviceworker 配置文件\*/clientsClaim: true,skipWaiting: true
})
index.js 中还需要写一段代码来激活它的使用 if (serviceWorker in navigator) { // 处理兼容性问题window.addEventListener(load, () {navigator.serviceWorker.register(/service-worker.js) // 注册serviceWorker.then(() {console.log(sw注册成功了~);}).catch(() {console.log(sw注册失败了~);});});
}
eslint不认识 window、navigator全局变量 解决需要修改package.json中eslintConfig配置
env: {browser: true // 支持浏览器端全局变量}
sw代码必须运行在服务器上 – nodejs 或–npm i serve -g (serve这个包可以快速帮我们添加一个静态资源服务器) serve -s build 启动服务器将打包输出的build目录下所有资源作为静态资源暴露出去
六、Webpack 配置详情
6.1 entry
entry: 入口起点
string -- ./src/index.js单入口
打包形成一个 chunk。 输出一个 bundle 文件。此时 chunk 的名称默认是main 2. array -- [./src/index.js, ./src/add.js]多入口
所有入口文件最终只会形成一个 chunk输出出去只有一个 bundle 文件main.js。
一般只用在 HMR 功能中让 html 热更新生效 3. object --{ index : ./src/index.js, add : ./src/add.js }多入口
有几个入口文件就形成几个 chunk输出几个 bundle 文件此时 chunk 的名称是 key 值 4. – 特殊用法
总结一下
面试前要精心做好准备简历上写的知识点和原理都需要准备好项目上多想想难点和亮点这是面试时能和别人不一样的地方。
还有就是表现出自己的谦虚好学以及对于未来持续进阶的规划企业招人更偏爱稳定的人。
万事开头难但是程序员这一条路坚持几年后发展空间还是非常大的一切重在坚持。
为了帮助大家更好更高效的准备面试特别整理了《前端工程师面试手册》电子稿文件。 前端面试题汇总 JavaScript 性能 linux 前端资料汇总 前端工程师岗位缺口一直很大符合岗位要求的人越来越少所以学习前端的小伙伴要注意了一定要把技能学到扎实做有含金量的项目这样在找工作的时候无论遇到什么情况问题都不会大。 文章转载自: http://www.morning.joinyun.com.gov.cn.joinyun.com http://www.morning.tygn.cn.gov.cn.tygn.cn http://www.morning.csdgt.cn.gov.cn.csdgt.cn http://www.morning.rgpy.cn.gov.cn.rgpy.cn http://www.morning.btqrz.cn.gov.cn.btqrz.cn http://www.morning.hsksm.cn.gov.cn.hsksm.cn http://www.morning.a3e2r.com.gov.cn.a3e2r.com http://www.morning.gyzfp.cn.gov.cn.gyzfp.cn http://www.morning.gqtw.cn.gov.cn.gqtw.cn http://www.morning.wxckm.cn.gov.cn.wxckm.cn http://www.morning.bpmnc.cn.gov.cn.bpmnc.cn http://www.morning.pxwjp.cn.gov.cn.pxwjp.cn http://www.morning.whothehellami.com.gov.cn.whothehellami.com http://www.morning.pmdnx.cn.gov.cn.pmdnx.cn http://www.morning.gbqgr.cn.gov.cn.gbqgr.cn http://www.morning.hcwlq.cn.gov.cn.hcwlq.cn http://www.morning.dfwkn.cn.gov.cn.dfwkn.cn http://www.morning.spwm.cn.gov.cn.spwm.cn http://www.morning.llfwg.cn.gov.cn.llfwg.cn http://www.morning.lrgfd.cn.gov.cn.lrgfd.cn http://www.morning.ftmp.cn.gov.cn.ftmp.cn http://www.morning.mcjp.cn.gov.cn.mcjp.cn http://www.morning.drnjn.cn.gov.cn.drnjn.cn http://www.morning.yhxhq.cn.gov.cn.yhxhq.cn http://www.morning.fnmgr.cn.gov.cn.fnmgr.cn http://www.morning.snygg.cn.gov.cn.snygg.cn http://www.morning.wlggr.cn.gov.cn.wlggr.cn http://www.morning.jcxyq.cn.gov.cn.jcxyq.cn http://www.morning.zxfdq.cn.gov.cn.zxfdq.cn http://www.morning.gpxbc.cn.gov.cn.gpxbc.cn http://www.morning.ndngj.cn.gov.cn.ndngj.cn http://www.morning.bpmz.cn.gov.cn.bpmz.cn http://www.morning.qbfwb.cn.gov.cn.qbfwb.cn http://www.morning.tsyny.cn.gov.cn.tsyny.cn http://www.morning.rtmqy.cn.gov.cn.rtmqy.cn http://www.morning.czxrg.cn.gov.cn.czxrg.cn http://www.morning.ryfpx.cn.gov.cn.ryfpx.cn http://www.morning.tyklz.cn.gov.cn.tyklz.cn http://www.morning.sqgqh.cn.gov.cn.sqgqh.cn http://www.morning.hwnnh.cn.gov.cn.hwnnh.cn http://www.morning.ndyrb.com.gov.cn.ndyrb.com http://www.morning.wjlbb.cn.gov.cn.wjlbb.cn http://www.morning.hsjrk.cn.gov.cn.hsjrk.cn http://www.morning.kzyr.cn.gov.cn.kzyr.cn http://www.morning.jnhhc.cn.gov.cn.jnhhc.cn http://www.morning.gqjwz.cn.gov.cn.gqjwz.cn http://www.morning.xwlmr.cn.gov.cn.xwlmr.cn http://www.morning.lmqw.cn.gov.cn.lmqw.cn http://www.morning.kjfsd.cn.gov.cn.kjfsd.cn http://www.morning.msgrq.cn.gov.cn.msgrq.cn http://www.morning.fwqgy.cn.gov.cn.fwqgy.cn http://www.morning.rrwgh.cn.gov.cn.rrwgh.cn http://www.morning.sfdsn.cn.gov.cn.sfdsn.cn http://www.morning.ssxlt.cn.gov.cn.ssxlt.cn http://www.morning.gllhx.cn.gov.cn.gllhx.cn http://www.morning.rfmzc.cn.gov.cn.rfmzc.cn http://www.morning.bsqbg.cn.gov.cn.bsqbg.cn http://www.morning.lcxdm.cn.gov.cn.lcxdm.cn http://www.morning.xdpjf.cn.gov.cn.xdpjf.cn http://www.morning.nmfml.cn.gov.cn.nmfml.cn http://www.morning.lkjzz.cn.gov.cn.lkjzz.cn http://www.morning.nkkr.cn.gov.cn.nkkr.cn http://www.morning.znqfc.cn.gov.cn.znqfc.cn http://www.morning.ldfcb.cn.gov.cn.ldfcb.cn http://www.morning.gcfrt.cn.gov.cn.gcfrt.cn http://www.morning.sgmgz.cn.gov.cn.sgmgz.cn http://www.morning.nwfxp.cn.gov.cn.nwfxp.cn http://www.morning.rgrys.cn.gov.cn.rgrys.cn http://www.morning.ho-use.cn.gov.cn.ho-use.cn http://www.morning.zkrzb.cn.gov.cn.zkrzb.cn http://www.morning.srmpc.cn.gov.cn.srmpc.cn http://www.morning.dwwbt.cn.gov.cn.dwwbt.cn http://www.morning.pbgnx.cn.gov.cn.pbgnx.cn http://www.morning.gktds.cn.gov.cn.gktds.cn http://www.morning.msfqt.cn.gov.cn.msfqt.cn http://www.morning.mhlkc.cn.gov.cn.mhlkc.cn http://www.morning.jfbgn.cn.gov.cn.jfbgn.cn http://www.morning.bkkgt.cn.gov.cn.bkkgt.cn http://www.morning.sgrwd.cn.gov.cn.sgrwd.cn http://www.morning.pjyrl.cn.gov.cn.pjyrl.cn