当前位置: 首页 > news >正文

微信商城和网站建设100个网络营销案例

微信商城和网站建设,100个网络营销案例,域名解析错误怎么解决,网络工程师的就业前景优化代码运行性能 Code Split 为什么 打包代码时会将所有 js 文件打包到一个文件中#xff0c;体积太大了。我们如果只要渲染首页#xff0c;就应该只加载首页的 js 文件#xff0c;其他文件不应该加载。 所以我们需要将打包生成的文件进行代码分割#xff0c;生成多个…优化代码运行性能 Code Split 为什么 打包代码时会将所有 js 文件打包到一个文件中体积太大了。我们如果只要渲染首页就应该只加载首页的 js 文件其他文件不应该加载。 所以我们需要将打包生成的文件进行代码分割生成多个 js 文件渲染哪个页面就只加载某个 js 文件这样加载的资源就少速度就更快。 是什么 代码分割Code Split主要做了两件事 分割文件将打包生成的文件进行分割生成多个 js 文件。按需加载需要哪个文件就加载哪个文件。 怎么用 代码分割实现方式有不同的方式为了更加方便体现它们之间的差异我们会分别创建新的文件来演示 1. 多入口 文件目录 ├── public ├── src | ├── app.js | └── main.js ├── package.json └── webpack.config.js下载包 npm i webpack webpack-cli html-webpack-plugin -D新建文件 内容无关紧要主要观察打包输出的结果 app.js console.log(hello app);main.js console.log(hello main);配置 // webpack.config.js const path require(path); const HtmlWebpackPlugin require(html-webpack-plugin);module.exports {// 单入口// entry: ./src/main.js,// 多入口entry: {main: ./src/main.js,app: ./src/app.js,},output: {path: path.resolve(__dirname, ./dist),// [name]是webpack命名规则使用chunk的name作为输出的文件名。// 什么是chunk打包的资源就是chunk输出出去叫bundle。// chunk的name是啥呢 比如 entry中xxx: ./src/xxx.js, name就是xxx。注意是前面的xxx和文件名无关。// 为什么需要这样命名呢如果还是之前写法main.js那么打包生成两个js文件都会叫做main.js会发生覆盖。(实际上会直接报错的)filename: js/[name].js,clear: true,},plugins: [new HtmlWebpackPlugin({template: ./public/index.html,}),],mode: production, };运行指令 npx webpack此时在 dist 目录我们能看到输出了两个 js 文件。 总结配置了几个入口至少输出几个 js 文件。 2. 提取重复代码 如果多入口文件中都引用了同一份代码我们不希望这份代码被打包到两个文件中导致代码重复体积更大。 我们需要提取多入口的重复代码只打包生成一个 js 文件其他文件引用它就好。 修改文件 app.js import { sum } from ./math;console.log(hello app); console.log(sum(1, 2, 3, 4));main.js import { sum } from ./math;console.log(hello main); console.log(sum(1, 2, 3, 4, 5));math.js export const sum (...args) {return args.reduce((p, c) p c, 0); };修改配置文件 // webpack.config.js const path require(path); const HtmlWebpackPlugin require(html-webpack-plugin);module.exports {// 单入口// entry: ./src/main.js,// 多入口entry: {main: ./src/main.js,app: ./src/app.js,},output: {path: path.resolve(__dirname, ./dist),// [name]是webpack命名规则使用chunk的name作为输出的文件名。// 什么是chunk打包的资源就是chunk输出出去叫bundle。// chunk的name是啥呢 比如 entry中xxx: ./src/xxx.js, name就是xxx。注意是前面的xxx和文件名无关。// 为什么需要这样命名呢如果还是之前写法main.js那么打包生成两个js文件都会叫做main.js会发生覆盖。(实际上会直接报错的)filename: js/[name].js,clean: true,},plugins: [new HtmlWebpackPlugin({template: ./public/index.html,}),],mode: production,optimization: {// 代码分割配置splitChunks: {chunks: all, // 对所有模块都进行分割// 以下是默认值// minSize: 20000, // 分割代码最小的大小// minRemainingSize: 0, // 类似于minSize最后确保提取的文件大小不能为0// minChunks: 1, // 至少被引用的次数满足条件才会代码分割// maxAsyncRequests: 30, // 按需加载时并行加载的文件的最大数量// maxInitialRequests: 30, // 入口js文件最大并行请求数量// enforceSizeThreshold: 50000, // 超过50kb一定会单独打包此时会忽略minRemainingSize、maxAsyncRequests、maxInitialRequests// cacheGroups: { // 组哪些模块要打包到一个组// defaultVendors: { // 组名// test: /[\\/]node_modules[\\/]/, // 需要打包到一起的模块// priority: -10, // 权重越大越高// reuseExistingChunk: true, // 如果当前 chunk 包含已从主 bundle 中拆分出的模块则它将被重用而不是生成新的模块// },// default: { // 其他没有写的配置会使用上面的默认值// minChunks: 2, // 这里的minChunks权重更大// priority: -20,// reuseExistingChunk: true,// },// },// 修改配置cacheGroups: {// 组哪些模块要打包到一个组// defaultVendors: { // 组名// test: /[\\/]node_modules[\\/]/, // 需要打包到一起的模块// priority: -10, // 权重越大越高// reuseExistingChunk: true, // 如果当前 chunk 包含已从主 bundle 中拆分出的模块则它将被重用而不是生成新的模块// },default: {// 其他没有写的配置会使用上面的默认值minSize: 0, // 我们定义的文件体积太小了所以要改打包的最小文件体积minChunks: 2,priority: -20,reuseExistingChunk: true,},},},}, };运行指令 npx webpack此时我们会发现生成 3 个 js 文件其中有一个就是提取的公共模块。 3. 按需加载动态导入 想要实现按需加载动态导入模块。还需要额外配置 修改文件 main.js console.log(hello main);document.getElementById(btn).onclick function () {// 动态导入 -- 实现按需加载// 即使只被引用了一次也会代码分割import(./math.js).then(({ sum }) {alert(sum(1, 2, 3, 4, 5));}); };app.js console.log(hello app);public/index.html !DOCTYPE html html langenheadmeta charsetUTF-8 /meta http-equivX-UA-Compatible contentIEedge /meta nameviewport contentwidthdevice-width, initial-scale1.0 /titleCode Split/title/headbodyh1hello webpack/h1button idbtn计算/button/body /html运行指令 npx webpack我们可以发现一旦通过 import 动态导入语法导入模块模块就被代码分割同时也能按需加载了。 4. 单入口 开发时我们可能是单页面应用SPA只有一个入口单入口。那么我们需要这样配置 const path require(path); const HtmlWebpackPlugin require(html-webpack-plugin);module.exports {// 单入口entry: ./src/main.js,// 多入口// entry: {// main: ./src/main.js,// app: ./src/app.js,// },output: {path: path.resolve(__dirname, ./dist),// [name]是webpack命名规则使用chunk的name作为输出的文件名。// 什么是chunk打包的资源就是chunk输出出去叫bundle。// chunk的name是啥呢 比如 entry中xxx: ./src/xxx.js, name就是xxx。注意是前面的xxx和文件名无关。// 为什么需要这样命名呢如果还是之前写法main.js那么打包生成两个js文件都会叫做main.js会发生覆盖。(实际上会直接报错的)filename: js/[name].js,clean: true,},plugins: [new HtmlWebpackPlugin({template: ./public/index.html,}),],mode: production,optimization: {// 代码分割配置splitChunks: {chunks: all, // 对所有模块都进行分割// 以下是默认值// minSize: 20000, // 分割代码最小的大小// minRemainingSize: 0, // 类似于minSize最后确保提取的文件大小不能为0// minChunks: 1, // 至少被引用的次数满足条件才会代码分割// maxAsyncRequests: 30, // 按需加载时并行加载的文件的最大数量// maxInitialRequests: 30, // 入口js文件最大并行请求数量// enforceSizeThreshold: 50000, // 超过50kb一定会单独打包此时会忽略minRemainingSize、maxAsyncRequests、maxInitialRequests// cacheGroups: { // 组哪些模块要打包到一个组// defaultVendors: { // 组名// test: /[\\/]node_modules[\\/]/, // 需要打包到一起的模块// priority: -10, // 权重越大越高// reuseExistingChunk: true, // 如果当前 chunk 包含已从主 bundle 中拆分出的模块则它将被重用而不是生成新的模块// },// default: { // 其他没有写的配置会使用上面的默认值// minChunks: 2, // 这里的minChunks权重更大// priority: -20,// reuseExistingChunk: true,// },// },}, };5. 更新配置 最终我们会使用单入口代码分割动态导入方式来进行配置。更新之前的配置文件。 // webpack.prod.js const os require(os); const path require(path); const ESLintWebpackPlugin require(eslint-webpack-plugin); const HtmlWebpackPlugin require(html-webpack-plugin); const MiniCssExtractPlugin require(mini-css-extract-plugin); const CssMinimizerPlugin require(css-minimizer-webpack-plugin); const TerserPlugin require(terser-webpack-plugin); const ImageMinimizerPlugin require(image-minimizer-webpack-plugin);// cpu核数 const threads os.cpus().length;// 获取处理样式的Loaders const getStyleLoaders (preProcessor) {return [MiniCssExtractPlugin.loader,css-loader,{loader: postcss-loader,options: {postcssOptions: {plugins: [postcss-preset-env, // 能解决大多数样式兼容性问题],},},},preProcessor,].filter(Boolean); };module.exports {entry: ./src/main.js,output: {path: path.resolve(__dirname, ../dist), // 生产模式需要输出filename: static/js/main.js, // 将 js 文件输出到 static/js 目录中clean: true,},module: {rules: [{oneOf: [{// 用来匹配 .css 结尾的文件test: /\.css$/,// use 数组里面 Loader 执行顺序是从右到左use: getStyleLoaders(),},{test: /\.less$/,use: getStyleLoaders(less-loader),},{test: /\.s[ac]ss$/,use: getStyleLoaders(sass-loader),},{test: /\.styl$/,use: getStyleLoaders(stylus-loader),},{test: /\.(png|jpe?g|gif|svg)$/,type: asset,parser: {dataUrlCondition: {maxSize: 10 * 1024, // 小于10kb的图片会被base64处理},},generator: {// 将图片文件输出到 static/imgs 目录中// 将图片文件命名 [hash:8][ext][query]// [hash:8]: hash值取8位// [ext]: 使用之前的文件扩展名// [query]: 添加之前的query参数filename: static/imgs/[hash:8][ext][query],},},{test: /\.(ttf|woff2?)$/,type: asset/resource,generator: {filename: static/media/[hash:8][ext][query],},},{test: /\.js$/,// exclude: /node_modules/, // 排除node_modules代码不编译include: path.resolve(__dirname, ../src), // 也可以用包含use: [{loader: thread-loader, // 开启多进程options: {workers: threads, // 数量},},{loader: babel-loader,options: {cacheDirectory: true, // 开启babel编译缓存cacheCompression: false, // 缓存文件不要压缩plugins: [babel/plugin-transform-runtime], // 减少代码体积},},],},],},],},plugins: [new ESLintWebpackPlugin({// 指定检查文件的根目录context: path.resolve(__dirname, ../src),exclude: node_modules, // 默认值cache: true, // 开启缓存// 缓存目录cacheLocation: path.resolve(__dirname,../node_modules/.cache/.eslintcache),threads, // 开启多进程}),new HtmlWebpackPlugin({// 以 public/index.html 为模板创建文件// 新的html文件有两个特点1. 内容和源文件一致 2. 自动引入打包生成的js等资源template: path.resolve(__dirname, ../public/index.html),}),// 提取css成单独文件new MiniCssExtractPlugin({// 定义输出文件名和目录filename: static/css/main.css,}),// css压缩// new CssMinimizerPlugin(),],optimization: {minimizer: [// css压缩也可以写到optimization.minimizer里面效果一样的new CssMinimizerPlugin(),// 当生产模式会默认开启TerserPlugin但是我们需要进行其他配置就要重新写了new TerserPlugin({parallel: threads, // 开启多进程}),// 压缩图片new ImageMinimizerPlugin({minimizer: {implementation: ImageMinimizerPlugin.imageminGenerate,options: {plugins: [[gifsicle, { interlaced: true }],[jpegtran, { progressive: true }],[optipng, { optimizationLevel: 5 }],[svgo,{plugins: [preset-default,prefixIds,{name: sortAttrs,params: {xmlnsOrder: alphabetical,},},],},],],},},}),],// 代码分割配置splitChunks: {chunks: all, // 对所有模块都进行分割// 其他内容用默认配置即可},},// devServer: {// host: localhost, // 启动服务器域名// port: 3000, // 启动服务器端口号// open: true, // 是否自动打开浏览器// },mode: production,devtool: source-map, };6. 给动态导入文件取名称 修改文件 main.js import sum from ./js/sum; // 引入资源Webpack才会对其打包 import ./css/iconfont.css; import ./css/index.css; import ./less/index.less; import ./sass/index.sass; import ./sass/index.scss; import ./styl/index.styl;const result2 sum(1, 2, 3, 4); console.log(result2);// 以下代码生产模式下会删除 if (module.hot) {module.hot.accept(./js/sum.js, function (sum) {const result2 sum(1, 2, 3, 4);console.log(result2);}); }document.getElementById(btn).onClick function () {// eslint会对动态导入语法报错需要修改eslint配置文件// webpackChunkName: math这是webpack动态导入模块命名的方式// math将来就会作为[name]的值显示。import(/* webpackChunkName: math */ ./js/math.js).then(({ count }) {console.log(count(2, 1));}); };eslint 配置 下载包 npm i eslint-plugin-import -D配置 // .eslintrc.js module.exports {// 继承 Eslint 规则extends: [eslint:recommended],env: {node: true, // 启用node中全局变量browser: true, // 启用浏览器中全局变量},plugins: [import], // 解决动态导入import语法报错问题 -- 实际使用eslint-plugin-import的规则解决的parserOptions: {ecmaVersion: 6,sourceType: module,},rules: {no-var: 2, // 不能使用 var 定义变量}, };统一命名配置 const os require(os); const path require(path); const ESLintWebpackPlugin require(eslint-webpack-plugin); const HtmlWebpackPlugin require(html-webpack-plugin); const MiniCssExtractPlugin require(mini-css-extract-plugin); const CssMinimizerPlugin require(css-minimizer-webpack-plugin); const TerserPlugin require(terser-webpack-plugin); const ImageMinimizerPlugin require(image-minimizer-webpack-plugin);// cpu核数 const threads os.cpus().length;// 获取处理样式的Loaders const getStyleLoaders (preProcessor) {return [MiniCssExtractPlugin.loader,css-loader,{loader: postcss-loader,options: {postcssOptions: {plugins: [postcss-preset-env, // 能解决大多数样式兼容性问题],},},},preProcessor,].filter(Boolean); };module.exports {entry: ./src/main.js,output: {path: path.resolve(__dirname, ../dist), // 生产模式需要输出filename: static/js/[name].js, // 入口文件打包输出资源命名方式chunkFilename: static/js/[name].chunk.js, // 动态导入输出资源命名方式assetModuleFilename: static/media/[name].[hash][ext], // 图片、字体等资源命名方式注意用hashclean: true,},module: {rules: [{oneOf: [{// 用来匹配 .css 结尾的文件test: /\.css$/,// use 数组里面 Loader 执行顺序是从右到左use: getStyleLoaders(),},{test: /\.less$/,use: getStyleLoaders(less-loader),},{test: /\.s[ac]ss$/,use: getStyleLoaders(sass-loader),},{test: /\.styl$/,use: getStyleLoaders(stylus-loader),},{test: /\.(png|jpe?g|gif|svg)$/,type: asset,parser: {dataUrlCondition: {maxSize: 10 * 1024, // 小于10kb的图片会被base64处理},},// generator: {// // 将图片文件输出到 static/imgs 目录中// // 将图片文件命名 [hash:8][ext][query]// // [hash:8]: hash值取8位// // [ext]: 使用之前的文件扩展名// // [query]: 添加之前的query参数// filename: static/imgs/[hash:8][ext][query],// },},{test: /\.(ttf|woff2?)$/,type: asset/resource,// generator: {// filename: static/media/[hash:8][ext][query],// },},{test: /\.js$/,// exclude: /node_modules/, // 排除node_modules代码不编译include: path.resolve(__dirname, ../src), // 也可以用包含use: [{loader: thread-loader, // 开启多进程options: {workers: threads, // 数量},},{loader: babel-loader,options: {cacheDirectory: true, // 开启babel编译缓存cacheCompression: false, // 缓存文件不要压缩plugins: [babel/plugin-transform-runtime], // 减少代码体积},},],},],},],},plugins: [new ESLintWebpackPlugin({// 指定检查文件的根目录context: path.resolve(__dirname, ../src),exclude: node_modules, // 默认值cache: true, // 开启缓存// 缓存目录cacheLocation: path.resolve(__dirname,../node_modules/.cache/.eslintcache),threads, // 开启多进程}),new HtmlWebpackPlugin({// 以 public/index.html 为模板创建文件// 新的html文件有两个特点1. 内容和源文件一致 2. 自动引入打包生成的js等资源template: path.resolve(__dirname, ../public/index.html),}),// 提取css成单独文件new MiniCssExtractPlugin({// 定义输出文件名和目录filename: static/css/[name].css,chunkFilename: static/css/[name].chunk.css,}),// css压缩// new CssMinimizerPlugin(),],optimization: {minimizer: [// css压缩也可以写到optimization.minimizer里面效果一样的new CssMinimizerPlugin(),// 当生产模式会默认开启TerserPlugin但是我们需要进行其他配置就要重新写了new TerserPlugin({parallel: threads, // 开启多进程}),// 压缩图片new ImageMinimizerPlugin({minimizer: {implementation: ImageMinimizerPlugin.imageminGenerate,options: {plugins: [[gifsicle, { interlaced: true }],[jpegtran, { progressive: true }],[optipng, { optimizationLevel: 5 }],[svgo,{plugins: [preset-default,prefixIds,{name: sortAttrs,params: {xmlnsOrder: alphabetical,},},],},],],},},}),],// 代码分割配置splitChunks: {chunks: all, // 对所有模块都进行分割// 其他内容用默认配置即可},},// devServer: {// host: localhost, // 启动服务器域名// port: 3000, // 启动服务器端口号// open: true, // 是否自动打开浏览器// },mode: production,devtool: source-map, };运行指令 npx webpack观察打包输出 js 文件名称。 Preload / Prefetch 为什么 我们前面已经做了代码分割同时会使用 import 动态导入语法来进行代码按需加载我们也叫懒加载比如路由懒加载就是这样实现的。 但是加载速度还不够好比如是用户点击按钮时才加载这个资源的如果资源体积很大那么用户会感觉到明显卡顿效果。 我们想在浏览器空闲时间加载后续需要使用的资源。我们就需要用上 Preload 或 Prefetch 技术。 是什么 Preload告诉浏览器立即加载资源。 Prefetch告诉浏览器在空闲时才开始加载资源。 它们共同点 都只会加载资源并不执行。都有缓存。 它们区别 Preload加载优先级高Prefetch加载优先级低。Preload只能加载当前页面需要使用的资源Prefetch可以加载当前页面资源也可以加载下一个页面需要使用的资源。 总结 当前页面优先级高的资源用 Preload 加载。下一个页面需要使用的资源用 Prefetch 加载。 它们的问题兼容性较差。 我们可以去 Can I Use 网站查询 API 的兼容性问题。Preload 相对于 Prefetch 兼容性好一点。 怎么用 下载包 npm i vue/preload-webpack-plugin -D配置 webpack.prod.js const os require(os); const path require(path); const ESLintWebpackPlugin require(eslint-webpack-plugin); const HtmlWebpackPlugin require(html-webpack-plugin); const MiniCssExtractPlugin require(mini-css-extract-plugin); const CssMinimizerPlugin require(css-minimizer-webpack-plugin); const TerserPlugin require(terser-webpack-plugin); const ImageMinimizerPlugin require(image-minimizer-webpack-plugin); const PreloadWebpackPlugin require(vue/preload-webpack-plugin);// cpu核数 const threads os.cpus().length;// 获取处理样式的Loaders const getStyleLoaders (preProcessor) {return [MiniCssExtractPlugin.loader,css-loader,{loader: postcss-loader,options: {postcssOptions: {plugins: [postcss-preset-env, // 能解决大多数样式兼容性问题],},},},preProcessor,].filter(Boolean); };module.exports {entry: ./src/main.js,output: {path: path.resolve(__dirname, ../dist), // 生产模式需要输出filename: static/js/[name].js, // 入口文件打包输出资源命名方式chunkFilename: static/js/[name].chunk.js, // 动态导入输出资源命名方式assetModuleFilename: static/media/[name].[hash][ext], // 图片、字体等资源命名方式注意用hashclean: true,},module: {rules: [{oneOf: [{// 用来匹配 .css 结尾的文件test: /\.css$/,// use 数组里面 Loader 执行顺序是从右到左use: getStyleLoaders(),},{test: /\.less$/,use: getStyleLoaders(less-loader),},{test: /\.s[ac]ss$/,use: getStyleLoaders(sass-loader),},{test: /\.styl$/,use: getStyleLoaders(stylus-loader),},{test: /\.(png|jpe?g|gif|svg)$/,type: asset,parser: {dataUrlCondition: {maxSize: 10 * 1024, // 小于10kb的图片会被base64处理},},// generator: {// // 将图片文件输出到 static/imgs 目录中// // 将图片文件命名 [hash:8][ext][query]// // [hash:8]: hash值取8位// // [ext]: 使用之前的文件扩展名// // [query]: 添加之前的query参数// filename: static/imgs/[hash:8][ext][query],// },},{test: /\.(ttf|woff2?)$/,type: asset/resource,// generator: {// filename: static/media/[hash:8][ext][query],// },},{test: /\.js$/,// exclude: /node_modules/, // 排除node_modules代码不编译include: path.resolve(__dirname, ../src), // 也可以用包含use: [{loader: thread-loader, // 开启多进程options: {workers: threads, // 数量},},{loader: babel-loader,options: {cacheDirectory: true, // 开启babel编译缓存cacheCompression: false, // 缓存文件不要压缩plugins: [babel/plugin-transform-runtime], // 减少代码体积},},],},],},],},plugins: [new ESLintWebpackPlugin({// 指定检查文件的根目录context: path.resolve(__dirname, ../src),exclude: node_modules, // 默认值cache: true, // 开启缓存// 缓存目录cacheLocation: path.resolve(__dirname,../node_modules/.cache/.eslintcache),threads, // 开启多进程}),new HtmlWebpackPlugin({// 以 public/index.html 为模板创建文件// 新的html文件有两个特点1. 内容和源文件一致 2. 自动引入打包生成的js等资源template: path.resolve(__dirname, ../public/index.html),}),// 提取css成单独文件new MiniCssExtractPlugin({// 定义输出文件名和目录filename: static/css/[name].css,chunkFilename: static/css/[name].chunk.css,}),// css压缩// new CssMinimizerPlugin(),new PreloadWebpackPlugin({rel: preload, // preload兼容性更好as: script,// rel: prefetch // prefetch兼容性更差}),],optimization: {minimizer: [// css压缩也可以写到optimization.minimizer里面效果一样的new CssMinimizerPlugin(),// 当生产模式会默认开启TerserPlugin但是我们需要进行其他配置就要重新写了new TerserPlugin({parallel: threads, // 开启多进程}),// 压缩图片new ImageMinimizerPlugin({minimizer: {implementation: ImageMinimizerPlugin.imageminGenerate,options: {plugins: [[gifsicle, { interlaced: true }],[jpegtran, { progressive: true }],[optipng, { optimizationLevel: 5 }],[svgo,{plugins: [preset-default,prefixIds,{name: sortAttrs,params: {xmlnsOrder: alphabetical,},},],},],],},},}),],// 代码分割配置splitChunks: {chunks: all, // 对所有模块都进行分割// 其他内容用默认配置即可},},// devServer: {// host: localhost, // 启动服务器域名// port: 3000, // 启动服务器端口号// open: true, // 是否自动打开浏览器// },mode: production,devtool: source-map, };Network Cache 为什么 将来开发时我们对静态资源会使用缓存来优化这样浏览器第二次请求资源就能读取缓存了速度很快。 但是这样的话就会有一个问题, 因为前后输出的文件名是一样的都叫 main.js一旦将来发布新版本因为文件名没有变化导致浏览器会直接读取缓存不会加载新资源项目也就没法更新了。 所以我们从文件名入手确保更新前后文件名不一样这样就可以做缓存了。 是什么 它们都会生成一个唯一的 hash 值。 fullhashwebpack4 是 hash 每次修改任何一个文件所有文件名的 hash 至都将改变。所以一旦修改了任何一个文件整个项目的文件缓存都将失效。 chunkhash 根据不同的入口文件(Entry)进行依赖文件解析、构建对应的 chunk生成对应的哈希值。我们 js 和 css 是同一个引入会共享一个 hash 值。 contenthash 根据文件内容生成 hash 值只有文件内容变化了hash 值才会变化。所有文件 hash 值是独享且不同的。 怎么用 const os require(os); const path require(path); const ESLintWebpackPlugin require(eslint-webpack-plugin); const HtmlWebpackPlugin require(html-webpack-plugin); const MiniCssExtractPlugin require(mini-css-extract-plugin); const CssMinimizerPlugin require(css-minimizer-webpack-plugin); const TerserPlugin require(terser-webpack-plugin); const ImageMinimizerPlugin require(image-minimizer-webpack-plugin); const PreloadWebpackPlugin require(vue/preload-webpack-plugin);// cpu核数 const threads os.cpus().length;// 获取处理样式的Loaders const getStyleLoaders (preProcessor) {return [MiniCssExtractPlugin.loader,css-loader,{loader: postcss-loader,options: {postcssOptions: {plugins: [postcss-preset-env, // 能解决大多数样式兼容性问题],},},},preProcessor,].filter(Boolean); };module.exports {entry: ./src/main.js,output: {path: path.resolve(__dirname, ../dist), // 生产模式需要输出// [contenthash:8]使用contenthash取8位长度filename: static/js/[name].[contenthash:8].js, // 入口文件打包输出资源命名方式chunkFilename: static/js/[name].[contenthash:8].chunk.js, // 动态导入输出资源命名方式assetModuleFilename: static/media/[name].[hash][ext], // 图片、字体等资源命名方式注意用hashclean: true,},module: {rules: [{oneOf: [{// 用来匹配 .css 结尾的文件test: /\.css$/,// use 数组里面 Loader 执行顺序是从右到左use: getStyleLoaders(),},{test: /\.less$/,use: getStyleLoaders(less-loader),},{test: /\.s[ac]ss$/,use: getStyleLoaders(sass-loader),},{test: /\.styl$/,use: getStyleLoaders(stylus-loader),},{test: /\.(png|jpe?g|gif|svg)$/,type: asset,parser: {dataUrlCondition: {maxSize: 10 * 1024, // 小于10kb的图片会被base64处理},},// generator: {// // 将图片文件输出到 static/imgs 目录中// // 将图片文件命名 [hash:8][ext][query]// // [hash:8]: hash值取8位// // [ext]: 使用之前的文件扩展名// // [query]: 添加之前的query参数// filename: static/imgs/[hash:8][ext][query],// },},{test: /\.(ttf|woff2?)$/,type: asset/resource,// generator: {// filename: static/media/[hash:8][ext][query],// },},{test: /\.js$/,// exclude: /node_modules/, // 排除node_modules代码不编译include: path.resolve(__dirname, ../src), // 也可以用包含use: [{loader: thread-loader, // 开启多进程options: {workers: threads, // 数量},},{loader: babel-loader,options: {cacheDirectory: true, // 开启babel编译缓存cacheCompression: false, // 缓存文件不要压缩plugins: [babel/plugin-transform-runtime], // 减少代码体积},},],},],},],},plugins: [new ESLintWebpackPlugin({// 指定检查文件的根目录context: path.resolve(__dirname, ../src),exclude: node_modules, // 默认值cache: true, // 开启缓存// 缓存目录cacheLocation: path.resolve(__dirname,../node_modules/.cache/.eslintcache),threads, // 开启多进程}),new HtmlWebpackPlugin({// 以 public/index.html 为模板创建文件// 新的html文件有两个特点1. 内容和源文件一致 2. 自动引入打包生成的js等资源template: path.resolve(__dirname, ../public/index.html),}),// 提取css成单独文件new MiniCssExtractPlugin({// 定义输出文件名和目录filename: static/css/[name].[contenthash:8].css,chunkFilename: static/css/[name].[contenthash:8].chunk.css,}),// css压缩// new CssMinimizerPlugin(),new PreloadWebpackPlugin({rel: preload, // preload兼容性更好as: script,// rel: prefetch // prefetch兼容性更差}),],optimization: {minimizer: [// css压缩也可以写到optimization.minimizer里面效果一样的new CssMinimizerPlugin(),// 当生产模式会默认开启TerserPlugin但是我们需要进行其他配置就要重新写了new TerserPlugin({parallel: threads, // 开启多进程}),// 压缩图片new ImageMinimizerPlugin({minimizer: {implementation: ImageMinimizerPlugin.imageminGenerate,options: {plugins: [[gifsicle, { interlaced: true }],[jpegtran, { progressive: true }],[optipng, { optimizationLevel: 5 }],[svgo,{plugins: [preset-default,prefixIds,{name: sortAttrs,params: {xmlnsOrder: alphabetical,},},],},],],},},}),],// 代码分割配置splitChunks: {chunks: all, // 对所有模块都进行分割// 其他内容用默认配置即可},},// devServer: {// host: localhost, // 启动服务器域名// port: 3000, // 启动服务器端口号// open: true, // 是否自动打开浏览器// },mode: production,devtool: source-map, };问题 当我们修改 math.js 文件再重新打包的时候因为 contenthash 原因math.js 文件 hash 值发生了变化这是正常的。 但是 main.js 文件的 hash 值也发生了变化这会导致 main.js 的缓存失效。明明我们只修改 math.js, 为什么 main.js 也会变身变化呢 原因 更新前math.xxx.js, main.js 引用的 math.xxx.js更新后math.yyy.js, main.js 引用的 math.yyy.js, 文件名发生了变化间接导致 main.js 也发生了变化 解决 将 hash 值单独保管在一个 runtime 文件中。 我们最终输出三个文件main、math、runtime。当 math 文件发送变化变化的是 math 和 runtime 文件main 不变。 runtime 文件只保存文件的 hash 值和它们与文件关系整个文件体积就比较小所以变化重新请求的代价也小。 const os require(os); const path require(path); const ESLintWebpackPlugin require(eslint-webpack-plugin); const HtmlWebpackPlugin require(html-webpack-plugin); const MiniCssExtractPlugin require(mini-css-extract-plugin); const CssMinimizerPlugin require(css-minimizer-webpack-plugin); const TerserPlugin require(terser-webpack-plugin); const ImageMinimizerPlugin require(image-minimizer-webpack-plugin); const PreloadWebpackPlugin require(vue/preload-webpack-plugin);// cpu核数 const threads os.cpus().length;// 获取处理样式的Loaders const getStyleLoaders (preProcessor) {return [MiniCssExtractPlugin.loader,css-loader,{loader: postcss-loader,options: {postcssOptions: {plugins: [postcss-preset-env, // 能解决大多数样式兼容性问题],},},},preProcessor,].filter(Boolean); };module.exports {entry: ./src/main.js,output: {path: path.resolve(__dirname, ../dist), // 生产模式需要输出// [contenthash:8]使用contenthash取8位长度filename: static/js/[name].[contenthash:8].js, // 入口文件打包输出资源命名方式chunkFilename: static/js/[name].[contenthash:8].chunk.js, // 动态导入输出资源命名方式assetModuleFilename: static/media/[name].[hash][ext], // 图片、字体等资源命名方式注意用hashclean: true,},module: {rules: [{oneOf: [{// 用来匹配 .css 结尾的文件test: /\.css$/,// use 数组里面 Loader 执行顺序是从右到左use: getStyleLoaders(),},{test: /\.less$/,use: getStyleLoaders(less-loader),},{test: /\.s[ac]ss$/,use: getStyleLoaders(sass-loader),},{test: /\.styl$/,use: getStyleLoaders(stylus-loader),},{test: /\.(png|jpe?g|gif|svg)$/,type: asset,parser: {dataUrlCondition: {maxSize: 10 * 1024, // 小于10kb的图片会被base64处理},},// generator: {// // 将图片文件输出到 static/imgs 目录中// // 将图片文件命名 [hash:8][ext][query]// // [hash:8]: hash值取8位// // [ext]: 使用之前的文件扩展名// // [query]: 添加之前的query参数// filename: static/imgs/[hash:8][ext][query],// },},{test: /\.(ttf|woff2?)$/,type: asset/resource,// generator: {// filename: static/media/[hash:8][ext][query],// },},{test: /\.js$/,// exclude: /node_modules/, // 排除node_modules代码不编译include: path.resolve(__dirname, ../src), // 也可以用包含use: [{loader: thread-loader, // 开启多进程options: {workers: threads, // 数量},},{loader: babel-loader,options: {cacheDirectory: true, // 开启babel编译缓存cacheCompression: false, // 缓存文件不要压缩plugins: [babel/plugin-transform-runtime], // 减少代码体积},},],},],},],},plugins: [new ESLintWebpackPlugin({// 指定检查文件的根目录context: path.resolve(__dirname, ../src),exclude: node_modules, // 默认值cache: true, // 开启缓存// 缓存目录cacheLocation: path.resolve(__dirname,../node_modules/.cache/.eslintcache),threads, // 开启多进程}),new HtmlWebpackPlugin({// 以 public/index.html 为模板创建文件// 新的html文件有两个特点1. 内容和源文件一致 2. 自动引入打包生成的js等资源template: path.resolve(__dirname, ../public/index.html),}),// 提取css成单独文件new MiniCssExtractPlugin({// 定义输出文件名和目录filename: static/css/[name].[contenthash:8].css,chunkFilename: static/css/[name].[contenthash:8].chunk.css,}),// css压缩// new CssMinimizerPlugin(),new PreloadWebpackPlugin({rel: preload, // preload兼容性更好as: script,// rel: prefetch // prefetch兼容性更差}),],optimization: {minimizer: [// css压缩也可以写到optimization.minimizer里面效果一样的new CssMinimizerPlugin(),// 当生产模式会默认开启TerserPlugin但是我们需要进行其他配置就要重新写了new TerserPlugin({parallel: threads, // 开启多进程}),// 压缩图片new ImageMinimizerPlugin({minimizer: {implementation: ImageMinimizerPlugin.imageminGenerate,options: {plugins: [[gifsicle, { interlaced: true }],[jpegtran, { progressive: true }],[optipng, { optimizationLevel: 5 }],[svgo,{plugins: [preset-default,prefixIds,{name: sortAttrs,params: {xmlnsOrder: alphabetical,},},],},],],},},}),],// 代码分割配置splitChunks: {chunks: all, // 对所有模块都进行分割// 其他内容用默认配置即可},// 提取runtime文件runtimeChunk: {name: (entrypoint) runtime~${entrypoint.name}, // runtime文件命名规则},},// devServer: {// host: localhost, // 启动服务器域名// port: 3000, // 启动服务器端口号// open: true, // 是否自动打开浏览器// },mode: production,devtool: source-map, };Core-js 为什么 过去我们使用 babel 对 js 代码进行了兼容性处理其中使用babel/preset-env 智能预设来处理兼容性问题。 它能将 ES6 的一些语法进行编译转换比如箭头函数、点点点运算符等。但是如果是 async 函数、promise 对象、数组的一些方法includes等它没办法处理。 所以此时我们 js 代码仍然存在兼容性问题一旦遇到低版本浏览器会直接报错。所以我们想要将 js 兼容性问题彻底解决 是什么 core-js 是专门用来做 ES6 以及以上 API 的 polyfill。 polyfill翻译过来叫做垫片/补丁。就是用社区上提供的一段代码让我们在不兼容某些新特性的浏览器上使用该新特性。 怎么用 修改 main.js import count from ./js/count; import sum from ./js/sum; // 引入资源Webpack才会对其打包 import ./css/iconfont.css; import ./css/index.css; import ./less/index.less; import ./sass/index.sass; import ./sass/index.scss; import ./styl/index.styl;const result1 count(2, 1); console.log(result1); const result2 sum(1, 2, 3, 4); console.log(result2); // 添加promise代码 const promise Promise.resolve(); promise.then(() {console.log(hello promise); });此时 Eslint 会对 Promise 报错。 修改配置文件 下载包 npm i babel/eslint-parser -D.eslintrc.js module.exports {// 继承 Eslint 规则extends: [eslint:recommended],parser: babel/eslint-parser, // 支持最新的最终 ECMAScript 标准env: {node: true, // 启用node中全局变量browser: true, // 启用浏览器中全局变量},plugins: [import], // 解决动态导入import语法报错问题 -- 实际使用eslint-plugin-import的规则解决的parserOptions: {ecmaVersion: 6, // es6sourceType: module, // es module},rules: {no-var: 2, // 不能使用 var 定义变量}, };运行指令 npm run build此时观察打包输出的 js 文件我们发现 Promise 语法并没有编译转换所以我们需要使用 core-js 来进行 polyfill。 使用core-js 下载包 npm i core-js手动全部引入 import core-js; import count from ./js/count; import sum from ./js/sum; // 引入资源Webpack才会对其打包 import ./css/iconfont.css; import ./css/index.css; import ./less/index.less; import ./sass/index.sass; import ./sass/index.scss; import ./styl/index.styl;const result1 count(2, 1); console.log(result1); const result2 sum(1, 2, 3, 4); console.log(result2); // 添加promise代码 const promise Promise.resolve(); promise.then(() {console.log(hello promise); });这样引入会将所有兼容性代码全部引入体积太大了。我们只想引入 promise 的 polyfill。 手动按需引入 import core-js/es/promise; import count from ./js/count; import sum from ./js/sum; // 引入资源Webpack才会对其打包 import ./css/iconfont.css; import ./css/index.css; import ./less/index.less; import ./sass/index.sass; import ./sass/index.scss; import ./styl/index.styl;const result1 count(2, 1); console.log(result1); const result2 sum(1, 2, 3, 4); console.log(result2); // 添加promise代码 const promise Promise.resolve(); promise.then(() {console.log(hello promise); });只引入打包 promise 的 polyfill打包体积更小。但是将来如果还想使用其他语法我需要手动引入库很麻烦。 自动按需引入 main.js import count from ./js/count; import sum from ./js/sum; // 引入资源Webpack才会对其打包 import ./css/iconfont.css; import ./css/index.css; import ./less/index.less; import ./sass/index.sass; import ./sass/index.scss; import ./styl/index.styl;const result1 count(2, 1); console.log(result1); const result2 sum(1, 2, 3, 4); console.log(result2); // 添加promise代码 const promise Promise.resolve(); promise.then(() {console.log(hello promise); });babel.config.js module.exports {// 智能预设能够编译ES6语法presets: [[babel/preset-env,// 按需加载core-js的polyfill{ useBuiltIns: usage, corejs: { version: 3, proposals: true } },],], };此时就会自动根据我们代码中使用的语法来按需加载相应的 polyfill 了。 PWA 为什么 开发 Web App 项目项目一旦处于网络离线情况就没法访问了。 我们希望给项目提供离线体验。 是什么 渐进式网络应用程序(progressive web application - PWA)是一种可以提供类似于 native app(原生应用程序) 体验的 Web App 的技术。 其中最重要的是在 离线(offline) 时应用程序能够继续运行功能。 内部通过 Service Workers 技术实现的。 怎么用 下载包 npm i workbox-webpack-plugin -D修改配置文件 const os require(os); const path require(path); const ESLintWebpackPlugin require(eslint-webpack-plugin); const HtmlWebpackPlugin require(html-webpack-plugin); const MiniCssExtractPlugin require(mini-css-extract-plugin); const CssMinimizerPlugin require(css-minimizer-webpack-plugin); const TerserPlugin require(terser-webpack-plugin); const ImageMinimizerPlugin require(image-minimizer-webpack-plugin); const PreloadWebpackPlugin require(vue/preload-webpack-plugin); const WorkboxPlugin require(workbox-webpack-plugin);// cpu核数 const threads os.cpus().length;// 获取处理样式的Loaders const getStyleLoaders (preProcessor) {return [MiniCssExtractPlugin.loader,css-loader,{loader: postcss-loader,options: {postcssOptions: {plugins: [postcss-preset-env, // 能解决大多数样式兼容性问题],},},},preProcessor,].filter(Boolean); };module.exports {entry: ./src/main.js,output: {path: path.resolve(__dirname, ../dist), // 生产模式需要输出// [contenthash:8]使用contenthash取8位长度filename: static/js/[name].[contenthash:8].js, // 入口文件打包输出资源命名方式chunkFilename: static/js/[name].[contenthash:8].chunk.js, // 动态导入输出资源命名方式assetModuleFilename: static/media/[name].[hash][ext], // 图片、字体等资源命名方式注意用hashclean: true,},module: {rules: [{oneOf: [{// 用来匹配 .css 结尾的文件test: /\.css$/,// use 数组里面 Loader 执行顺序是从右到左use: getStyleLoaders(),},{test: /\.less$/,use: getStyleLoaders(less-loader),},{test: /\.s[ac]ss$/,use: getStyleLoaders(sass-loader),},{test: /\.styl$/,use: getStyleLoaders(stylus-loader),},{test: /\.(png|jpe?g|gif|svg)$/,type: asset,parser: {dataUrlCondition: {maxSize: 10 * 1024, // 小于10kb的图片会被base64处理},},// generator: {// // 将图片文件输出到 static/imgs 目录中// // 将图片文件命名 [hash:8][ext][query]// // [hash:8]: hash值取8位// // [ext]: 使用之前的文件扩展名// // [query]: 添加之前的query参数// filename: static/imgs/[hash:8][ext][query],// },},{test: /\.(ttf|woff2?)$/,type: asset/resource,// generator: {// filename: static/media/[hash:8][ext][query],// },},{test: /\.js$/,// exclude: /node_modules/, // 排除node_modules代码不编译include: path.resolve(__dirname, ../src), // 也可以用包含use: [{loader: thread-loader, // 开启多进程options: {workers: threads, // 数量},},{loader: babel-loader,options: {cacheDirectory: true, // 开启babel编译缓存cacheCompression: false, // 缓存文件不要压缩plugins: [babel/plugin-transform-runtime], // 减少代码体积},},],},],},],},plugins: [new ESLintWebpackPlugin({// 指定检查文件的根目录context: path.resolve(__dirname, ../src),exclude: node_modules, // 默认值cache: true, // 开启缓存// 缓存目录cacheLocation: path.resolve(__dirname,../node_modules/.cache/.eslintcache),threads, // 开启多进程}),new HtmlWebpackPlugin({// 以 public/index.html 为模板创建文件// 新的html文件有两个特点1. 内容和源文件一致 2. 自动引入打包生成的js等资源template: path.resolve(__dirname, ../public/index.html),}),// 提取css成单独文件new MiniCssExtractPlugin({// 定义输出文件名和目录filename: static/css/[name].[contenthash:8].css,chunkFilename: static/css/[name].[contenthash:8].chunk.css,}),// css压缩// new CssMinimizerPlugin(),new PreloadWebpackPlugin({rel: preload, // preload兼容性更好as: script,// rel: prefetch // prefetch兼容性更差}),new WorkboxPlugin.GenerateSW({// 这些选项帮助快速启用 ServiceWorkers// 不允许遗留任何“旧的” ServiceWorkersclientsClaim: true,skipWaiting: true,}),],optimization: {minimizer: [// css压缩也可以写到optimization.minimizer里面效果一样的new CssMinimizerPlugin(),// 当生产模式会默认开启TerserPlugin但是我们需要进行其他配置就要重新写了new TerserPlugin({parallel: threads, // 开启多进程}),// 压缩图片new ImageMinimizerPlugin({minimizer: {implementation: ImageMinimizerPlugin.imageminGenerate,options: {plugins: [[gifsicle, { interlaced: true }],[jpegtran, { progressive: true }],[optipng, { optimizationLevel: 5 }],[svgo,{plugins: [preset-default,prefixIds,{name: sortAttrs,params: {xmlnsOrder: alphabetical,},},],},],],},},}),],// 代码分割配置splitChunks: {chunks: all, // 对所有模块都进行分割// 其他内容用默认配置即可},},// devServer: {// host: localhost, // 启动服务器域名// port: 3000, // 启动服务器端口号// open: true, // 是否自动打开浏览器// },mode: production,devtool: source-map, };修改 main.js import count from ./js/count; import sum from ./js/sum; // 引入资源Webpack才会对其打包 import ./css/iconfont.css; import ./css/index.css; import ./less/index.less; import ./sass/index.sass; import ./sass/index.scss; import ./styl/index.styl;const result1 count(2, 1); console.log(result1); const result2 sum(1, 2, 3, 4); console.log(result2); // 添加promise代码 const promise Promise.resolve(); promise.then(() {console.log(hello promise); });const arr [1, 2, 3, 4, 5]; console.log(arr.includes(5));if (serviceWorker in navigator) {window.addEventListener(load, () {navigator.serviceWorker.register(/service-worker.js).then((registration) {console.log(SW registered: , registration);}).catch((registrationError) {console.log(SW registration failed: , registrationError);});}); }运行指令 npm run build此时如果直接通过 VSCode 访问打包后页面在浏览器控制台会发现 SW registration failed。 因为我们打开的访问路径是http://127.0.0.1:5500/dist/index.html。此时页面会去请求 service-worker.js 文件请求路径是http://127.0.0.1:5500/service-worker.js这样找不到会 404。 实际 service-worker.js 文件路径是http://127.0.0.1:5500/dist/service-worker.js。 解决路径问题 下载包 npm i serve -gserve 也是用来启动开发服务器来部署代码查看效果的。 运行指令 serve dist此时通过 serve 启动的服务器我们 service-worker 就能注册成功了。
http://www.pierceye.com/news/668031/

相关文章:

  • 动物网站建设wordpress无法跳转正确页面
  • 上海市建设工程 安全协会网站wordpress会员微信支付宝
  • pc网站转换手机网站代码桂林工作网招聘
  • 营销型网站建设的要素怎么建网站赚钱
  • 成都网站建设学习郑州制作网站推荐
  • 网站建设 镇江丹阳php网站开发实例教程代码
  • 佛山外贸网站建设方案专业网站建设系统
  • 做一个网站团队需要哪些人员花钱也可以哪些网站可以做推广广告
  • 各省施工备案网站做动漫网站的素材
  • 新余网站设计网站模板做网站
  • 防止服务器上的网站被进攻app推广兼职
  • 保定电商网站建设国内最好的crm软件
  • 企业网站建设哪家公司好莱芜金点子信息港房产网
  • 个人可以建设网站吗海淀网站建设本溪
  • 宜昌网站建设兼职怎样做自媒体拍视频赚钱
  • 我的世界做视频封面的网站免费的app源码网
  • 网站搭建wordpress参考消息电子版在线阅读
  • 成立一个网站平台要多少钱科技有限公司一般是做什么的
  • 邵阳 网站开发 招聘桂林阳朔楼盘最新价格
  • 如何建设网站导航内链接wordpress 特别慢
  • 蚌埠网站建设文章网站软件定制开发公司
  • 软件通网站建设百度收录网站电话
  • 取消网站备案制度正规的电商平台有哪些
  • 茶叶网站源码php6731官方网站下载
  • 网站建设mfdos 优帮云制作简历哪个网站好
  • 淮南市城乡建设局网站网站seo收费
  • 陕西手机网站制作描述网站开发的广告词
  • 一个网址建多个网站手机网站数据加载
  • 网站视觉分析上海做saas平台网站的公司
  • 沈阳网站设计网站一键制作