最新文�? 动力电池系列之软包电池产业链:孚能科技VS亿纬锂能VS欣旺达,半固态电池进展技术产能规划 光伏系列之下游组件产业链跟踪:天合光能VS晶澳科技VS隆基绿能,产能规划一体化进展未来关键变化 周期系列之猪周期+黄羽鸡产业链跟踪:温氏股份VS湘佳股份VS立华股份,出栏量鲜品占比成本育种能力 新能源车高压化系列之软磁材料产业链:东睦股份VS铂科新材,技术趋势产能规划客户 动力电池系列之整线设备产业链:先导智能VS利元亨VS赢合科技,订单体量合同负债一体化趋势
原创 : Webpack5学习笔记(持续更新) 历史版本:
上次修改时间:
; eslint-config-airbnb-base eslint-plugin-import eslint\n */\n {\n test: /\\.js$/,\n // 不需要语法检查的路径\n exclude: /node_modules/,\n // 指定检查的目录\n include: [path.resolve(__dirname, \'src\')],\n loader: \'eslint-loader\',\n // 编译前检查\n enforce: \'pre\'\n options: {\n // 自动修复\n fix: true,\n },,\n },\n ],\n },\n plugins: [\n new HtmlWebpackPlugin({ template: \'./src/index.html\' }),\n new MiniCssExtractPlugin({ filename: \'css/built.css\' }),\n // 压缩css\n new OptimizeCssAssetsWebpackPlugin(),\n ],\n\n mode: \'development\',\n devServer: {\n // 项目构建后路径\n contentBase: resolve(__dirname, \'build\'),\n // 启动 gzip 压缩\n compress: true,\n // 端口号\n port: 3000,\n // 自动打开浏览器\n open: true,\n },\n};\n\n```\n\n###### 3. 配置 package.json\n\n```\n\"eslintConfig\": {\n \"extends\": \"airbnb-base\",\n \"env\": {\n \"browser\": true\n }\n }\n\n```\n\n###### 4. 运行指令:\n\n```\nwebpack\n\n```\n\n备注:\n\n### 4.5 js 兼容性处理\n\n###### 1. 下载安装包\n\n```\nnpm install --save -dev babel-loader @babel/core @babel/preset-env @babel/polyfill core-js\n\n```\n\n###### 2. 修改配置文件\n\n```\nconst { resolve } = require(\'path\');\nconst HtmlWebpackPlugin = require(\'html-webpack-plugin\');\nconst MiniCssExtractPlugin = require(\'mini-css-extract-plugin\');\nconst OptimizeCssAssetsWebpackPlugin = require(\'optimize-css-assets-webpack-plugin\');\n// 设置nodejs环境变量,默認是生产环境\n// process.env.NODE_ENV = \'development\';\nmodule.exports = {\n entry: \'./src/js/index.js\',\n output: {\n filename: \'js/built.js\',\n path: resolve(__dirname, \'build\'),\n publicPath: \'/build/\',\n },\n module: {\n rules: [\n {\n test: /\\.css$/,\n use: [\n // \'style-loader\',\n MiniCssExtractPlugin.loader,\n \'css-loader\',\n {\n loader: \'postcss-loader\',\n options: { postcssOptions: { ident: \'postcss\', plugins: [require(\'postcss-preset-env\')()] } },\n },\n ],\n },\n {\n test: /\\.less$/,\n use: [\n // \'style-loader\',\n MiniCssExtractPlugin.loader,\n \'css-loader\',\n {\n loader: \'postcss-loader\',\n options: { \n postcssOptions: { \n ident: \"postcss\", \n plugins: [require(\"postcss-preset-env\")()] } \n }\n },\n \'less-loader\',\n ],\n },\n {\n test: /\\.(gif|img|png|jpg)$/,\n loader: \'url-loader\',\n options: {\n limit: 8 * 1024,\n name: \'[hash:10].[ext]\',\n esModule: false,\n outputPath: \'images\',\n },\n },\n {\n // 处理 html 中 img 资源\n test: /\\.(html|htm)$/i,\n use: \'html-withimg-loader\', // 解析 html中的图片资源\n },\n {\n exclude: /\\.(css|js|html|less|gif|img|png|jpg)$/,\n loader: \'file-loader\',\n options: {\n name: \'[hash:10].[ext]\',\n outputPath: \'assets\',\n },\n },\n /*\n 语法检查: eslint-loader eslint\n 注意:只检查自己写的源代码,第三方的库是不用检查的\n 设置检查规则: package.json 中 eslintConfig 中设置~\n \"eslintConfig\": {\n \"extends\": \"airbnb-base\"\n }\n airbnb 需要的语法依赖-->; eslint-config-airbnb-base eslint-plugin-import eslint\n */\n {\n test: /\\.js$/,\n // 不需要语法检查的路径\n exclude: /node_modules/,\n // 指定检查的目录\n include: [resolve(__dirname, \'src\')],\n loader: \'eslint-loader\',\n // 编译前先检查\n enforce: \'pre\',\n options: {\n // 自动修复\n fix: true,\n },\n },\n /*\n js兼容性处理:需要下载 babel-loader @babel/core\n 1. 基本js兼容性处理 -->; @babel/preset-env\n 问题:只能转换基本语法,如promise高级语法不能转换\n 2. 全部js兼容性处理 -->; @babel/polyfill\n 问题:只要解决部分兼容性问题,但是将所有兼容性代码全部引入,体积太大了\n 3. 需要做兼容性处理的就做:按需加载 -->; core-js\n 最終方案:@babel/preset-env + core-js\n */\n {\n test: /\\.js$/,\n exclude: /node_module/,\n loader: \'babel-loader\',\n options: {\n presets: [\n [\n // 基本预设\n \'@babel/preset-env\',\n {\n // 按需加载\n useBuiltIns: \'usage\',\n // 指定core-js版本\n corejs: { version: 3 },\n // 指定兼容到什么版本的浏览器\n targets: {\n chrome: \'60\',\n firefox: \'50\',\n ie: \'9\',\n safari: \'10\',\n edge: \'17\',\n },\n },\n ],\n ],\n },\n },\n ],\n },\n plugins: [\n new HtmlWebpackPlugin({ template: \'./src/index.html\' }),\n new MiniCssExtractPlugin({ filename: \'css/built.css\' }),\n // 压缩css\n new OptimizeCssAssetsWebpackPlugin(),\n ],\n\n mode: \'development\',\n devServer: {\n // 项目构建后路径\n contentBase: resolve(__dirname, \'build\'),\n // 启动 gzip 压缩\n compress: true,\n // 端口号\n port: 3000,\n // 自动打开浏览器\n open: true,\n },\n};\n\n```\n\n###### 3.执行\n\n```\nwebpack\n\n```\n\n###### 4.执行效果\n\n![](https://www.testingcloud.club/sapi/api/image_download/a4c28b67-89db-11ef-b381-00163e13fc6a.png)\n\n### 4.6 js 压缩和HTML 压缩\n\n#### 4.6.1 js 压缩\n\n生产环境下会自动压缩 js 代码;在webopack.config.js文件中直接修改mode即可\n\n```\n mode: \'production\' \n\n```\n\n#### 4.6.2 HTML 压缩\n\n我们在使用HtmlWebpackPlugin 时候新增minify配置项即可\n\n```\n new HtmlWebpackPlugin({\n template: \'./src/index.html\',\n minify: {\n // 移除空格:\n collapseWhitespace: true,\n // 移除注释\n removeComments: true\n }\n }),\n\n```\n\n### 4.7总结:webpack生产环境配置总结:\n\n###### 1.文件目錄\n\n![](https://www.testingcloud.club/sapi/api/image_download/a54eb1df-89db-11ef-b381-00163e13fc6a.png)\n\n###### 2.webpack配置文件\n\n```\nconst { resolve } = require(\'path\');\nconst HtmlWebpackPlugin = require(\'html-webpack-plugin\');\n// 用于css生产单独文件\nconst MiniCssExtractPlugin = require(\'mini-css-extract-plugin\');\n// 压缩css\nconst OptimizeCssAssetsWebpackPlugin = require(\'optimize-css-assets-webpack-plugin\');\n// 设置nodejs环境变量,默認是生产环境\nprocess.env.NODE_ENV = \'development\';\n// 复用css的loader配置\nconst commCssLoader = [\n MiniCssExtractPlugin.loader,\n \'css-loader\',\n {\n loader: \'postcss-loader\',\n options: {\n postcssOptions: {\n ident: \'postcss\',\n plugins: [require(\'postcss-preset-env\')()]\n }\n },\n }]\nmodule.exports = {\n entry: \'./src/js/index.js\',\n output: {\n filename: \'js/built.js\',\n path: resolve(__dirname, \'build\'),\n publicPath: \'/build/\',\n },\n module: {\n rules: [\n {\n test: /\\.css$/,\n use: [\n ...commCssLoader\n ],\n },\n {\n test: /\\.less$/,\n use: [\n ...commCssLoader,\n \'less-loader\',\n ],\n },\n {\n test: /\\.(gif|img|png|jpg)$/,\n loader: \'url-loader\',\n options: {\n limit: 8 * 1024,\n name: \'[hash:10].[ext]\',\n esModule: false,\n outputPath: \'images\',\n },\n },\n {\n // 处理 html 中 img 资源\n test: /\\.(html|htm)$/i,\n use: \'html-withimg-loader\', // 解析 html中的图片资源\n },\n {\n exclude: /\\.(css|js|html|less|gif|img|png|jpg)$/,\n loader: \'file-loader\',\n options: {\n name: \'[hash:10].[ext]\',\n outputPath: \'assets\',\n },\n },\n /*\n 语法检查: eslint-loader eslint\n 注意:只检查自己写的源代码,第三方的库是不用检查的\n 设置检查规则: package.json 中 eslintConfig 中设置~\n \"eslintConfig\": {\n \"extends\": \"airbnb-base\"\n }\n airbnb 需要的语法依赖-->; eslint-config-airbnb-base eslint-plugin-import eslint\n */\n {\n test: /\\.js$/,\n // 不需要语法检查的路径\n exclude: /node_modules/,\n // 指定检查的目录\n include: [resolve(__dirname, \'src\')],\n loader: \'eslint-loader\',\n // 优先执行(先做检查,再执行兼容性处理)\n enforce: \'pre\',\n options: {\n // 自动修复\n fix: true,\n },\n },\n /*\n js兼容性处理:需要下载 babel-loader @babel/core\n 1. 基本js兼容性处理 -->; @babel/preset-env\n 问题:只能转换基本语法,如promise高级语法不能转换\n 2. 全部js兼容性处理 -->; @babel/polyfill\n 问题:只要解决部分兼容性问题,但是将所有兼容性代码全部引入,体积太大了\n 3. 需要做兼容性处理的就做:按需加载 -->; core-js\n 最終方案:@babel/preset-env + core-js\n */\n {\n test: /\\.js$/,\n exclude: /node_module/,\n loader: \'babel-loader\',\n options: {\n presets: [\n [\n // 基本预设\n \'@babel/preset-env\',\n {\n // 按需加载\n useBuiltIns: \'usage\',\n // 指定core-js版本\n corejs: { version: 3 },\n // 指定兼容到什么版本的浏览器\n targets: {\n chrome: \'60\',\n firefox: \'50\',\n ie: \'9\',\n safari: \'10\',\n edge: \'17\',\n },\n },\n ],\n ],\n },\n },\n ],\n },\n plugins: [\n new HtmlWebpackPlugin({\n template: \'./src/index.html\',\n minify: {\n // 移除空格:\n collapseWhitespace: true,\n // 移除注释\n removeComments: true\n }\n }),\n new MiniCssExtractPlugin({ filename: \'css/built.css\' }),\n // 压缩css\n new OptimizeCssAssetsWebpackPlugin(),\n ],\n // 生产环境(production)下会压缩js文件\n mode: \'production\',\n devServer: {\n // 项目构建后路径\n contentBase: resolve(__dirname, \'build\'),\n // 启动 gzip 压缩\n compress: true,\n // 端口号\n port: 3000,\n // 自动打开浏览器\n open: true,\n },\n};\n\n```\n\n###### 3.package.json\n\n```\n\"browserslist\": {\n \"development\": [\n \"last 1 chrome version\",\n \"last 1 firefox version\",\n \"last 1 safari version\"\n ],\n \"production\": [\n \">;0.1%\",\n \"not dead\",\n \"not op_mini all\"\n ]\n },\n \"eslintConfig\": {\n \"extends\": \"airbnb-base\",\n \"env\": {\n \"browser\": true\n }\n }\n\n```\n\n## 5.webpack 优化配置\n\n###### 优化分为以下几个方面:\n\n### 5.1 开发环境性能优化\n\n#### 5.1.1 HMR :\n\n启用热替换模块(Hot Module Replacement),也被称为 HMR。
作用:一个模块发生变化,只会重新打包构建这一个模块(而不是打包所有模块) ,极大提升构建速度
代码:只需要在 devServer 中设置 hot 为 true,就会自动开启HMR功能(只能在开发模式下使用)\n\n```\ndevServer: {\n contentBase: resolve(__dirname, \'build\'),\n compress: true,\n port: 3000,\n open: true,\n // 开启HMR功能\n // 当修改了webpack配置,新配置要想生效,必须重启webpack服务\n hot: true\n}\n\n```\n\n每种文件实现热模块替换的情况:
样式文件:可以使用HMR功能,因为开发环境下使用的 style-loader 内部默认实现了热模块替换功能
js 文件:默认不能使用HMR功能(修改一个 js 模块所有 js 模块都会刷新)
–>; 实现 HMR 需要修改 js 代码(添加支持 HMR 功能的代码)
在index.js文件中:\n\n```\n// 绑定\nif (module.hot) {\n // 一旦 module.hot 为true,说明开启了HMR功能。 -->; 让HMR功能代码生效\n module.hot.accept(\'./print.js\', function() {\n // 方法会监听 print.js 文件的变化,一旦发生变化,只有这个模块会重新打包构建,其他模块不会。\n // 会执行后面的回调函数\n print();\n });\n}\n\n```\n\n注意:HMR 功能对 js 的处理,只能处理非入口 js 文件的其他文件。
html 文件: 默认不能使用 HMR 功能(html 不用做 HMR 功能,因为只有一个 html 文件,不需要再优化)
使用 HMR 会导致问题:html 文件不能热更新了(不会自动打包构建)
解决:修改 entry 入口,将 html 文件引入(这样 html 修改整体刷新)
entry: [’./src/js/index.js’, ‘./src/index.html’]\n\n#### 5.1.2 source-map\n\nsource-map:
一种提供源代码到构建后代码的映射的技术 (如果构建后代码出错了,通过映射可以追踪源代码错误)
参数:
[inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map\n\n代码:\n\n```\ndevtool: \'eval-source-map\'\n\n```\n\n可选方案:[生成source-map的位置|给出的错误代码信息]
1 **.source-map** :外部,错误代码准确信息 和 源代码的错误位置
![](https://www.testingcloud.club/sapi/api/image_download/a5c4f433-89db-11ef-b381-00163e13fc6a.png)\n\n2.**inline-source-map**:内联,只生成一个内联 source-map,错误代码准确信息 和 源代码的错误位置
![](https://www.testingcloud.club/sapi/api/image_download/a638a265-89db-11ef-b381-00163e13fc6a.png)\n\n3.**hidden-source-map**:外部,错误代码错误原因,但是没有错误位置(为了隐藏源代码),不能追踪源代码错误,只能提示到构建后代码的错误位置
![](https://www.testingcloud.club/sapi/api/image_download/a6a8d903-89db-11ef-b381-00163e13fc6a.png)\n\n4.**eval-source-map**:内联,每一个文件都生成对应的 source-map,都在 eval 中,错误代码准确信息 和 源代码的错误位
![](https://www.testingcloud.club/sapi/api/image_download/a7421738-89db-11ef-b381-00163e13fc6a.png)\n\n5.**nosources-source-map**:外部,错误代码准确信息,但是没有任何源代码信息(为了隐藏源代码)
![](https://www.testingcloud.club/sapi/api/image_download/a7bfc0aa-89db-11ef-b381-00163e13fc6a.png)\n\n6.**cheap-source-map**:外部,错误代码准确信息 和 源代码的错误位置,只能把错误精确到整行,忽略列
![](https://www.testingcloud.club/sapi/api/image_download/a84d7000-89db-11ef-b381-00163e13fc6a.png)\n\n7.**cheap-module-source-map**:外部,错误代码准确信息 和 源代码的错误位置,module 会加入 loader 的 source-map\n\n**内联 和 外部的区别:**\n1. 外部生成了文件,内联没有1. 内联构建速度更快\n开发/生产环境可做的选择:\n\n###### 开发环境 :\n\n```\n需要考虑速度快,调试更友好:\n 速度快( eval >; inline >; cheap >;... )\n eval-cheap-souce-map\n eval-source-map\n*调试更友好:\n souce-map\n cheap-module-souce-map\n cheap-souce-map\n\n```\n\n**最终得出最好的两种方案 :**
1.eval-source-map(完整度高,内联速度快,脚手架默认使用) /
2.eval-cheap-module-souce-map(错误提示忽略列但是包含其他信息,内联速度快)\n\n###### 生产环境:\n\n```\n需要考虑源代码要不要隐藏,调试要不要更友好\n内联会让代码体积变大,所以在生产环境不用内联\n隐藏源代码\nnosources-source-map 全部隐藏\nhidden-source-map 只隐藏源代码,会提示构建后代码错误信息\n\n```\n\n**最终得出最好的两种方案 :**
1.source-map(最完整)
2.cheap-module-souce-map(错误提示一整行忽略列)\n\n### 5.2 生产环境性能优化\n\n#### 5.2.1 优化打包构建速度\n\n##### 5.2.1.1 oneOf\n\n**oneOf**:匹配到 loader 后就不再向后进行匹配,优化生产环境的打包构建速度
代码:\n\n```\nmodule: {\n rules: [\n {\n // js 语法检查\n test: /\\.js$/,\n exclude: /node_modules/,\n // 优先执行\n enforce: \'pre\',\n loader: \'eslint-loader\',\n options: {\n fix: true\n }\n },\n {\n // oneOf 优化生产环境的打包构建速度\n // 以下loader只会匹配一个(匹配到了后就不会再往下匹配了)\n // 注意:不能有两个配置处理同一种类型文件(所以把eslint-loader提取出去放外面)\n oneOf: [\n {\n test: /\\.css$/,\n use: [...commonCssLoader]\n },\n {\n test: /\\.less$/,\n use: [...commonCssLoader, \'less-loader\']\n },\n {\n // js 兼容性处理\n test: /\\.js$/,\n exclude: /node_modules/,\n loader: \'babel-loader\',\n options: {\n presets: [\n [\n \'@babel/preset-env\',\n {\n useBuiltIns: \'usage\',\n corejs: {version: 3},\n targets: {\n chrome: \'60\',\n firefox: \'50\'\n }\n }\n ]\n ]\n }\n },\n {\n test: /\\.(jpg|png|gif)/,\n loader: \'url-loader\',\n options: {\n limit: 8 * 1024,\n name: \'[hash:10].[ext]\',\n outputPath: \'imgs\',\n esModule: false\n }\n },\n {\n test: /\\.html$/,\n loader: \'html-loader\'\n },\n {\n exclude: /\\.(js|css|less|html|jpg|png|gif)/,\n loader: \'file-loader\',\n options: {\n outputPath: \'media\'\n }\n }\n ]\n }\n ]\n},\n\n```\n\n##### 5.2.1.2 babel 缓存\n\nbabel 缓存:类似 HMR,将 babel 处理后的资源缓存起来(哪里的 js 改变就更新哪里,其他 js 还是用之前缓存的资源),让第二次打包构建速度更快
代码:\n\n```\n{\n test: /\\.js$/,\n exclude: /node_modules/,\n loader: \'babel-loader\',\n options: {\n presets: [\n [\n \'@babel/preset-env\',\n {\n useBuiltIns: \'usage\',\n corejs: { version: 3 },\n targets: {\n chrome: \'60\',\n firefox: \'50\'\n }\n }\n ]\n ],\n // 开启babel缓存\n // 第二次构建时,会读取之前的缓存\n cacheDirectory: true\n }\n},\n\n```\n\n##### 5.2.1.3 文件资源缓存\n\n文件名不变,就不会重新请求,而是再次用之前缓存的资源
1.hash: 每次 wepack 打包时会生成一个唯一的 hash 值。\n\n```\noutput: {\n // 文件名加hash值可防止缓存\n filename: \'js/built.[hash:10].js\',\n path: resolve(__dirname, \'build\'),\n publicPath: \'/build/\',\n },\n\n```\n\n```\nnew MiniCssExtractPlugin({ filename: \'css/built.[hash:10].css\' }),\n\n```\n\n​ 问题:重新打包,所有文件的 hsah 值都改变,会导致所有缓存失效。(可能只改动了一个文件)
2.chunkhash:根据 chunk 生成的 hash 值。来源于同一个 chunk的 hash 值一样
​ 问题:js 和 css 来自同一个chunk,hash 值是一样的(因为 css-loader 会将 css 文件加载到 js 中,所以同属于一个chunk)\n\n```\noutput: {\n // 文件名加hash值可防止缓存\n filename: \'js/built.[chunkhash:10].js\',\n path: resolve(__dirname, \'build\'),\n publicPath: \'/build/\',\n },\n\n```\n\n```\nnew MiniCssExtractPlugin({ filename: \'css/built.[chunkhash:10].css\' }),\n\n```\n\n3.contenthash: 根据文件的内容生成 hash 值。不同文件 hash 值一定不一样(文件内容修改,文件名里的 hash 才会改变)
修改 css 文件内容,打包后的 css 文件名 hash 值就改变,而 js 文件没有改变 hash 值就不变,这样 css 和 js 缓存就会分开判断要不要重新请求资源 -->; 让代码上线运行缓存更好使用\n\n```\noutput: {\n // 文件名加hash值可防止缓存\n filename: \'js/built.[contenthash:10].js\',\n path: resolve(__dirname, \'build\'),\n publicPath: \'/build/\',\n },\n\n```\n\n```\nnew MiniCssExtractPlugin({ filename: \'css/built.[contenthash:10].css\' }),\n\n```\n\n打包后文件名:
![](https://www.testingcloud.club/sapi/api/image_download/a8c38e60-89db-11ef-b381-00163e13fc6a.png)\n\n修改index.js代码再打包,不修改css代码
![](https://www.testingcloud.club/sapi/api/image_download/a9420889-89db-11ef-b381-00163e13fc6a.png)\n\n##### 5.2.1.4 tree shaking 树摇\n\n前提:\n1. 必须使用 ES6 模块化1. 开启 production 环境,会自动使用树摇(这样就自动会把无用代码去掉)
作用:去除无用代码,减少代码体积
在 package.json 中配置:\n```\n\"sideEffects\": false\n\n```\n\n表示所有代码都没有副作用(都可以进行 tree shaking)
这样会导致的问题:可能会把 css / @babel/polyfill 文件干掉(副作用);这些文件都只是引入,没有使用,所以因为树摇这些文件就不会被打包了
所以可以配置:\n\n```\n\"sideEffects\": [\"*.css\", \"*.less\"] \n\n```\n\n不会对css/less文件tree shaking处理\n\n##### 5.2.1.5 code split(代码分割)\n\n代码分割。将打包输出的一个大的 bundle.js 文件拆分成多个小文件,这样可以并行加载多个文件,比加载一个文件更快。
1.多入口拆分(多页面应用可以使用此方法)\n\n```\nentry: {\n // 多入口:有一个入口,最终输出就有一个bundle\n index: \'./src/js/index.js\',\n test: \'./src/js/test.js\'\n },\n output: {\n // [name]:取文件名\n filename: \'js/[name].[contenthash:10].js\',\n path: resolve(__dirname, \'build\')\n },\n\n```\n\n打包后输出文件
![](https://www.testingcloud.club/sapi/api/image_download/a9b1a5d6-89db-11ef-b381-00163e13fc6a.png)\n\n2.optimization:\n\n```\noptimization: {\n splitChunks: {\n chunks: \'all\'\n }\n },\n\n```\n\n将 node_modules 中的代码单独打包(大小超过30kb)
自动分析多入口chunk中,有没有公共的文件。如果有会打包成单独一个chunk(比如两个模块中都引入了jquery会被打包成单独的文件)(大小超过30kb),
例子
如果我们在index.js中引入jquery第三方工具后打包:
不加optimization配置打包:
![](https://www.testingcloud.club/sapi/api/image_download/aa268618-89db-11ef-b381-00163e13fc6a.png)\n\n加optimization配置打包:
![](https://www.testingcloud.club/sapi/api/image_download/aa8df382-89db-11ef-b381-00163e13fc6a.png)\n\n其中86kb就是我们引入的jquery代码;就算有多个入口文件都引用了jquery,jquery也只会被打包一次
3.import 动态导入语法:通过js代码,让某个文件被单独打包成一个chunk\n\n```\n/*\n import动态导入语法:能将某个文件单独打包(test文件不会和index打包在同一个文件而是单独打包)\n webpackChunkName:指定test单独打包后文件的名字\n*/\nimport(/* webpackChunkName: \'test\' */\'./test\')\n .then(({ mul, count }) =>; {\n // 文件加载成功~\n // eslint-disable-next-line\n console.log(mul(2, 5));\n })\n .catch(() =>; {\n // eslint-disable-next-line\n console.log(\'文件加载失败~\');\n });\n\n```\n\n4.总结:常用方案是 单入口文件+optimization\n\n##### 5.2.1.6 lazy loading(懒加载/预加载)\n\n1.懒加载:当文件需要使用时才加载(需要代码分割)。但是如果资源较大,加载时间就会较长,有延迟。
2.正常加载:可以认为是并行加载(同一时间加载多个文件)没有先后顺序,先加载了不需要的资源就会浪费时间。
3.预加载 prefetch(兼容性很差):会在使用之前,提前加载。等其他资源加载完毕,浏览器空闲了,再偷偷加载这个资源。这样在使用时已经加载好了,速度很快。所以在懒加载的基础上加上预加载会更好。\n\n代码:
index.js文件中\n\n```\ndocument.getElementById(\'btn\').onclick = function() {\n // 将import的内容放在异步回调函数中使用,点击按钮,test.js才会被加载(不会重复加载)\n // webpackPrefetch: true表示开启预加载\n import(/* webpackChunkName: \'test\', webpackPrefetch: true */\'./test\').then(({ mul }) =>; {\n console.log(mul(4, 5));\n });\n import(\'./test\').then(({ mul }) =>; {\n console.log(mul(2, 5))\n })\n};\n\n```\n\n分析:点击了btn按钮之后就回去加载test.js文件再调用mul()函数,当第二次点击时就直接从缓存中取并调用mul()函数
注意:
webpack懶加載打包时会報錯’import’ and ‘export’ may only appear at the top level
![](https://www.testingcloud.club/sapi/api/image_download/ab0081b3-89db-11ef-b381-00163e13fc6a.png)\n\n解决方案:
1.安装babel-eslint\n\n```\nnpm install --save-dev babel-eslint\n\n```\n\n2.新建 .eslintrc文件\n\n```\n{\n \"parser\": \"babel-eslint\",\n \"parserOptions\": {\n \"sourceType\": \"module\",\n \"allowImportExportEverywhere\": true\n }\n}\n\n```\n\n##### 5.2.1.7 pwa(离线可访问技术)\n\npwa:离线可访问技术(渐进式网络开发应用程序),使用 serviceworker 和 workbox 技术。优点是离线也能访问,缺点是兼容性差。
webpack.config.js 中配置:
1.安装:workbox-webpack-plugin:\n\n```\nnpm install workbox-webpack-plugin --save-dev\n\n```\n\n2.使用\n\n```\nconst WorkboxWebpackPlugin = require(\'workbox-webpack-plugin\'); // 引入插件\n\n// plugins中加入:\nnew WorkboxWebpackPlugin.GenerateSW({\n /*\n 1. 帮助serviceworker快速启动\n 2. 删除旧的 serviceworker\n\n 生成一个 serviceworker 配置文件\n */\n clientsClaim: true,\n skipWaiting: true\n})\n\n```\n\n3.修改package.json中eslintConfig配置(eslint不认识 window、navigator全局变量)\n\n```\n\"eslintConfig\": {\n ......\n \"env\": {\n \"browser\": true\n }\n }\n\n```\n\n4.1. serviceWorker代码必须运行在服务器上\n\n```\n npm i serve -g\n\n```\n\n4.2,启动服务器,将打包输出的build目录下所有资源作为静态资源暴露出去\n\n```\nserve -s build \n\n```\n\n5.注册serviceWorker:index.js 中还需要写一段代码来激活它的使用\n\n```\nif (\'serviceWorker\' in navigator) { // 处理兼容性问题\n window.addEventListener(\'load\', () =>; {\n navigator.serviceWorker\n .register(\'/service-worker.js\') // 注册serviceWorker\n .then(() =>; {\n console.log(\'sw注册成功了~\');\n })\n .catch(() =>; {\n console.log(\'sw注册失败了~\');\n });\n });\n}\n\n```\n\n##### 5.2.1.8 多进程打包\n\n多进程打包:某个任务消耗时间较长会卡顿,多进程可以同一时间干多件事,效率更高。
优点:是提升打包速度,
缺点:是每个进程的开启和交流都会有开销(babel-loader消耗时间最久,所以使用thread-loader针对其进行优化)
js代码非常多时,使用多进程打包效果会很明显\n\n```\n{\n test: /\\.js$/,\n exclude: /node_modules/,\n use: [\n /* \n thread-loader会对其后面的loader(这里是babel-loader)开启多进程打包。 \n 进程启动大概为600ms,进程通信也有开销。(启动的开销比较昂贵,不要滥用)\n 只有工作消耗时间比较长,才需要多进程打包\n */\n {\n loader: \'thread-loader\',\n options: {\n workers: 2 // 进程2个\n }\n },\n {\n loader: \'babel-loader\',\n options: {\n presets: [\n [\n \'@babel/preset-env\',\n {\n useBuiltIns: \'usage\',\n corejs: { version: 3 },\n targets: {\n chrome: \'60\',\n firefox: \'50\'\n }\n }\n ]\n ],\n // 开启babel缓存\n // 第二次构建时,会读取之前的缓存\n cacheDirectory: true\n }\n }\n ]\n},\n\n```\n\n在简单的项目中使用多线程打包:
![](https://www.testingcloud.club/sapi/api/image_download/ab6ff018-89db-11ef-b381-00163e13fc6a.png)\n\n不使用多线程打包:
![](https://www.testingcloud.club/sapi/api/image_download/abd72dec-89db-11ef-b381-00163e13fc6a.png)\n\n##### 5.2.1.9 externals\n\n```\nexternals:让某些库不打包,通过 cdn 引入\nwebpack.config.js 中配置:\nexternals: {\n // 拒绝jQuery被打包进来(通过cdn引入,速度会快一些)\n // 忽略的库名 -- npm包名\n jquery: \'jQuery\'\n}\n\n```\n\n需要在 index.html 中通过 cdn 引入:\n\n```\n<;script src=\"https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js\">;<;/script>;\n\n```\n\n##### 5.2.1.10 dll\n\ndll:让某些库单独打包,后直接引入到 build 中。可以在 code split 分割出 node_modules 后再用 dll 更细的分割,优化代码运行的性能。
1.新增 webpack.dll.js文件,并配置:(将 jquery 单独打包)\n\n```\n/*\n node_modules的库会打包到一起,但是很多库的时候打包输出的js文件就太大了\n 使用dll技术,对某些库(第三方库:jquery、react、vue...)进行单独打包\n 当运行webpack时,默认查找webpack.config.js配置文件\n 需求:需要运行webpack.dll.js文件\n -->; webpack --config webpack.dll.js(运行这个指令表示以这个配置文件打包)\n*/\nconst { resolve } = require(\'path\');\nconst webpack = require(\'webpack\');\n\nmodule.exports = {\n entry: {\n // 最终打包生成的[name] -->; jquery\n // [\'jquery] -->; 要打包的库是jquery\n jquery: [\'jquery\']\n },\n output: {\n // 输出出口指定\n filename: \'[name].js\', // name就是jquery\n path: resolve(__dirname, \'dll\'), // 打包到dll目录下\n library: \'[name]_[hash]\', // 打包的库里面向外暴露出去的内容叫什么名字\n },\n plugins: [\n // 打包生成一个manifest.json -->; 提供jquery的映射关系(告诉webpack:jquery之后不需要再打包和暴露内容的名称)\n new webpack.DllPlugin({\n name: \'[name]_[hash]\', // 映射库的暴露的内容名称\n path: resolve(__dirname, \'dll/manifest.json\') // 输出文件路径\n })\n ],\n mode: \'production\'\n};\n\n```\n\n2.运行这个指令表示以这个配置文件打包 (即单独打包node_module里的 依赖)\n\n```\nwebpack --config webpack.dll.js\n\n```\n\n3.webpack.config.js 配置:(告诉 webpack 不需要再打包 jquery,并将之前打包好的 jquery 跟其他打包好的资源一同输出到 build 目录下)\n\n```\n// 引入插件\nconst webpack = require(\'webpack\');\nconst AddAssetHtmlWebpackPlugin = require(\'add-asset-html-webpack-plugin\');\n\n// plugins中配置:\nplugins: [\n new HtmlWebpackPlugin({\n template: \'./src/index.html\'\n }),\n // 告诉webpack哪些库不参与打包,同时使用时的名称也得变\n new webpack.DllReferencePlugin({\n manifest: resolve(__dirname, \'dll/manifest.json\')\n }),\n // 将某个文件打包输出到build目录下,并在html中自动引入该资源\n new AddAssetHtmlWebpackPlugin({\n filepath: resolve(__dirname, \'dll/jquery.js\')\n })\n],\n\n```\n\n4.打包\n\n```\nwebpack\n\n```\n\n5.总结:
1.配置好webpack.dll.js 文件告诉webpack那些依赖包需要单独打包
2.执行:webpack --config webpack.dll.js,单独打包,并单独被打包的资源路径记录在manifest.json资源映射文件中
![](https://www.testingcloud.club/sapi/api/image_download/ac3fc01a-89db-11ef-b381-00163e13fc6a.png)
3.执行 webpack 开始项目打包,打包过程中manifest.json拿到单独被打包的资源路径并引入到index.html文件中
![](https://www.testingcloud.club/sapi/api/image_download/aca6e9d8-89db-11ef-b381-00163e13fc6a.png)\n\n## 6.webpack配置详解\n\n```\nentry: 入口起点\nstring -->; \'./src/index.js\',单入口\n打包形成一个 chunk。 输出一个 bundle 文件。此时 chunk 的名称默认是 main\narray -->; [\'./src/index.js\', \'./src/add.js\'],多入口\n所有入口文件最终只会形成一个 chunk,输出出去只有一个 bundle 文件。\n(一般只用在 HMR 功能中让 html 热更新生效)\nobject,多入口\n有几个入口文件就形成几个 chunk,输出几个 bundle 文件,此时 chunk 的名称是 key 值\n-->; 特殊用法:\nentry: {\n // 最终只会形成一个chunk, 输出出去只有一个bundle文件。\n index: [\'./src/index.js\', \'./src/count.js\'], \n // 形成一个chunk,输出一个bundle文件。\n add: \'./src/add.js\'\n}\n\n```\n\n### 6.2 output\n\n```\noutput: {\n // 文件名称(指定名称+目录)\n filename: \'js/[name].js\',\n // 输出文件目录(将来所有资源输出的公共目录)\n path: resolve(__dirname, \'build\'),\n // 所有资源引入公共路径前缀 -->; \'imgs/a.jpg\' -->; \'/imgs/a.jpg\'\n publicPath: \'/\',\n chunkFilename: \'js/[name]_chunk.js\', // 指定非入口chunk的名称\n library: \'[name]\', // 打包整个库后向外暴露的变量名\n libraryTarget: \'window\' // 变量名添加到哪个上 browser:window\n // libraryTarget: \'global\' // node:global\n // libraryTarget: \'commonjs\' // conmmonjs模块 exports\n},\n\n```\n\n### 6.3 module\n\n```\nmodule: {\n rules: [\n // loader的配置\n {\n test: /\\.css$/,\n // 多个loader用use\n use: [\'style-loader\', \'css-loader\']\n },\n {\n test: /\\.js$/,\n // 排除node_modules下的js文件\n exclude: /node_modules/,\n // 只检查src下的js文件\n include: resolve(__dirname, \'src\'),\n enforce: \'pre\', // 优先执行\n // enforce: \'post\', // 延后执行\n // 单个loader用loader\n loader: \'eslint-loader\',\n options: {} // 指定配置选项\n },\n {\n // 以下配置只会生效一个\n oneOf: []\n }\n ]\n},\n\n```\n\n### 6.4 resolve\n\n```\n// 解析模块的规则\nresolve: {\n // 配置解析模块路径别名: 优点:当目录层级很复杂时,简写路径;缺点:路径不会提示\n alias: {\n $css: resolve(__dirname, \'src/css\')\n },\n // 配置省略文件路径的后缀名(引入时就可以不写文件后缀名了)\n extensions: [\'.js\', \'.json\', \'.jsx\', \'.css\'],\n // 告诉 webpack 解析模块应该去找哪个目录\n modules: [resolve(__dirname, \'../../node_modules\'), \'node_modules\']\n}\n\n```\n\n这样配置后,引入文件就可以这样简写:import ‘$css/index’;\n\n### 6.5 dev server\n\n```\ndevServer: {\n // 运行代码所在的目录\n contentBase: resolve(__dirname, \'build\'),\n // 监视contentBase目录下的所有文件,一旦文件变化就会reload\n watchContentBase: true,\n watchOptions: {\n // 忽略文件\n ignored: /node_modules/\n },\n // 启动gzip压缩\n compress: true,\n // 端口号\n port: 5000,\n // 域名\n host: \'localhost\',\n // 自动打开浏览器\n open: true,\n // 开启HMR功能\n hot: true,\n // 不要显示启动服务器日志信息\n clientLogLevel: \'none\',\n // 除了一些基本信息外,其他内容都不要显示\n quiet: true,\n // 如果出错了,不要全屏提示\n overlay: false,\n // 服务器代理,-->; 解决开发环境跨域问题\n proxy: {\n // 一旦devServer(5000)服务器接收到/api/xxx的请求,就会把请求转发到另外一个服务器3000\n \'/api\': {\n target: \'http://localhost:3000\',\n // 发送请求时,请求路径重写:将/api/xxx -->; /xxx (去掉/api)\n pathRewrite: {\n \'^/api\': \'\'\n }\n }\n }\n}\n\n```\n\n其中,跨域问题:同源策略中不同的协议、端口号、域名就会产生跨域。
正常的浏览器和服务器之间有跨域,但是服务器之间没有跨域。代码通过代理服务器运行,所以浏览器和代理服务器之间没有跨域,浏览器把请求发送到代理服务器上,代理服务器替你转发到另外一个服务器上,服务器之间没有跨域,所以请求成功。代理服务器再把接收到的响应响应给浏览器。这样就解决开发环境下的跨域问题。\n\n### 6.6 optimization\n\ncontenthash 缓存会导致一个问题:修改 a 文件导致 b 文件 contenthash 变化。
因为在 index.js 中引入 a.js,打包后 index.js 中记录了 a.js 的 hash 值,而 a.js 改变,其重新打包后的 hash 改变,导致 index.js 文件内容中记录的 a.js 的 hash 也改变,从而重新打包后 index.js 的 hash 值也会变,这样就会使缓存失效。(改变的是a.js文件但是 index.js 文件的 hash 值也改变了)
解决办法:runtimeChunk -->; 将当前模块记录其他模块的 hash 单独打包为一个文件 runtime,这样 a.js 的 hash 改变只会影响 runtime 文件,不会影响到 index.js 文件\n\n```\noutput: {\n filename: \'js/[name].[contenthash:10].js\',\n path: resolve(__dirname, \'build\'),\n chunkFilename: \'js/[name].[contenthash:10]_chunk.js\' // 指定非入口文件的其他chunk的名字加_chunk\n},\noptimization: {\n splitChunks: {\n chunks: \'all\',\n /* 以下都是splitChunks默认配置,可以不写\n miniSize: 30 * 1024, // 分割的chunk最小为30kb(大于30kb的才分割)\n maxSize: 0, // 最大没有限制\n minChunks: 1, // 要提取的chunk最少被引用1次\n maxAsyncRequests: 5, // 按需加载时并行加载的文件的最大数量为5\n maxInitialRequests: 3, // 入口js文件最大并行请求数量\n automaticNameDelimiter: \'~\', // 名称连接符\n name: true, // 可以使用命名规则\n cacheGroups: { // 分割chunk的组\n vendors: {\n // node_modules中的文件会被打包到vendors组的chunk中,-->; vendors~xxx.js\n // 满足上面的公共规则,大小超过30kb、至少被引用一次\n test: /[\\\\/]node_modules[\\\\/]/,\n // 优先级\n priority: -10\n },\n default: {\n // 要提取的chunk最少被引用2次\n minChunks: 2,\n prority: -20,\n // 如果当前要打包的模块和之前已经被提取的模块是同一个,就会复用,而不是重新打包\n reuseExistingChunk: true\n }\n } */\n },\n // 将index.js记录的a.js的hash值单独打包到runtime文件中,防止修改a文件导致b文件的hash值变化,最后index.js文件里的应用b的文件名没变会出问题\n runtimeChunk: {\n name: entrypoint =>; `runtime-${entrypoint.name}`\n },\n minimizer: [\n // 配置生产环境的压缩方案:js/css\n new TerserWebpackPlugin({\n // 开启缓存\n cache: true,\n // 开启多进程打包\n parallel: true,\n // 启用sourceMap(否则会被压缩掉)\n sourceMap: true\n })\n ]\n}\n\n```\n -->
0条评�?
全部评论

关于博主

an actually real engineer

通信工程专业毕业,7年开发经验

技术栈:

精通c/c++

精通golang

熟悉常见的脚本,js,lua,python,php

熟悉电路基础,嵌入式,单片机

耕耘领域:

服务端开发

嵌入式开发

git

>

gin接口代码CURD生成工具

sql ddl to struct and markdown,将sql表自动化生成代码内对应的结构体和markdown表格格式,节省宝贵的时间。

输入ddl:
输出代码:

qt .ui文件转css文件

duilib xml 自动生成绑定控件代码

协议调试器

基于lua虚拟机的的协议调试器软件 支持的协议有:

串口

tcp客户端/服务端

udp 组播/udp节点

tcp websocket 客户端/服务端

软件界面

使用例子: 通过脚本来获得接收到的数据并写入文件和展示在界面上

下载地址和源码

duilib版本源码 qt qml版本源码 二进制包

webrtc easy demo

webrtc c++ native 库 demo 实现功能:

基于QT

webrtc摄像头/桌面捕获功能

opengl渲染/多播放窗格管理

janus meeting room

下载地址和源码

源码 二进制包

wifi,蓝牙 - 无线开关

实现功能:

通过wifi/蓝牙实现远程开关电器或者其他电子设备

电路原理图:

实物图:

深度学习验证工具

vtk+pcl 点云编辑工具

实现功能:

1. 点云文件加载显示(.pcd obj stl)

2. 点云重建

3. 点云三角化

4. 点云缩放

下载地址:

源码 二进制包

虚拟示波器

硬件实物图:

实现原理

基本性能

采集频率: 取决于外部adc模块和ebaz4205矿板的以太网接口速率,最高可以达到100M/8 约为12.5MPS

上位机实现功能: 采集,显示波形,存储wave文件。

参数可运行时配置

上位机:

显示缓冲区大小可调

刷新率可调节

触发显示刷新可调节

进程守护工具

基本功能:

1. 守护进程,被守护程序崩溃后自动重启。

2. 进程输出获取,显示在编辑框中。

二进制包

openblt 烧录工具

基本功能:

1. 加载openblt 文件,下载到具有openblt bootloader 运行的单片机中。

二进制包

opencv 功能验证工具(开源项目二次开发)

基本功能:

1. 插件化图像处理流程,支持自定义图像处理流程。 2. 完善的日志和权限管理

二进制包

又一个modbus调试工具

最近混迹物联网企业,发现目前缺少一个简易可用的modbus调试工具,本软件旨在为开发者提供一个简单modbus测试工具。
主打一个代码简单易修改。
特点:

1. 基于QT5

2. 基于libmodbus

3. 三方库完全跨平台,linux/windows。

二进制包

屏幕录制工具

1. 基于QT5

2. 基于ffmpeg

3. 支持自定义录屏

源代码

开源plutosdr 板卡

1. 完全开源

2. 提高固件定制服务

3. 硬件售价450 手焊产量有线

测试数据

内部DDS回环测试

接收测试

外部发送500MHZ FM波形

硬件原理图

matlab测试

2TRX版本

大部分plutosdr应用场景都是讲plutosdr板卡作为射频收发器来使用。
实际上plutosdr板卡本身运行linux 操作系统。是具有一定脱机运算的能力。 对于一些微型频谱检测,简单射频信号收发等应用完全可以将应用层直接实现在板卡上
相较于通过网卡或者USB口传输具有更稳定,带宽更高等优点。
本开源板卡由于了SD卡启动,较原版pluto支持了自定义启动应用的功能。
提供了应用层开发SDK(编译器,buildroot文件系统)。
通过usb连接电脑,经过RNDIS驱动可以近似为通过网卡连接
(支持固件的开发定制)。

二次开发例子

``` all:
arm-linux-gnueabihf-gcc -mfloat-abi=hard --sysroot=/root/v0.32_2trx/buildroot/output/staging -std=gnu99 -g -o pluto_stream ad9361-iiostream.c -lpthread -liio -lm -Wall -Wextra -lrt
clean:
rm pluto_stream

bsdiff算法补丁生成器

1. 官方bsdiff算法例子自带bzip压缩方式

2. 本例子没有压缩,直接生成补丁文件

3. 图形化界面基于DUILIB

二进制文件

版面分析即分析出图片内的具体文件元素,如文档标题,文档内容,文档页码等,本工具基于cnstd模型

Base64 Image

. 闽ICP备19002644号