【Webpack】模块打包工具 Webpack 的各种使用方式 淩亂°似流年 2022-12-17 07:30 320阅读 0赞 ## 1. Webpack 简介 ## * Webpack 是一个现代 JavaScript 的静态模块打包器(module bundler); * 那为什么要用这种构建工具进行打包呢?答:解决模块依赖和兼容性; * 打包器(构建工具)会将所有依赖关系按照规则合并为单个 JS 文件,一次加载; * 最终,生成浏览器能够使用的静态资源,下图为官方宣传效果图: ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2dvbmd4aWZhY2FpX2JlbGlldmU_size_16_color_FFFFFF_t_70_pic_center][] ## 2. 安装 Webpack ## * 既然 Webpack 是 JavaScript 打包工具,那自然学前基础必然是 HTML5 和 ES6+; * 安装需要使用 npm(或 cnpm),需要去安装 Node.js,开发工具使用 Webstorm; * 找到官网下载 node.js,任意版本均可,下载安装,在命令行测试版本号: >> node -v * 创建一个 Webstorm 项目,准备使用 npm 安装,可以先测试版本好: >> npm -v >> npm config get registry // 查看镜像,不是国内,设置淘宝镜像即可 >> npm config set registry https://registry.npm.taobao.org * 有时 npm 命令不太稳定,报错的话,可以使用 cnpm,语法一模一样; >> npm install -g cnpm --registry=https://registry.npm.taobao.org * 安装好 npm 或 cnpm 后,测试 webpack 命令是否有效,如下: >> webpack -v * 首先,先全局安装,需要两个:webpack 核心模块、webpack-cli 命令行工具; * 其中:install 可以简写为 i,-g 表示全局; >> npm i webpack webpack-cli -g * 或者:在本地的项目中安装 webpack,–save-dev 可以简写为-D; >> npm i webpack webpack-cli -D * 官方推荐使用本地安装,这样如果有多版本的话,不会导致冲突; * 而本地安装,就只能在本项目中使用 webpack 命令,并且需要 npx 命令。 ## 3. 模块打包 ## * 我们创建 02 目录,在其创建约定俗成的两个子目录 src 和 dist; * 其中:src 表示源文件,dist 表示生成发布的文件; * 在 src 中建立两个 js 文件,用 node 环境支持的 CommonJS 规范的模块化; // module.js module.exports = { 'Mr.Lee' }; // index.js const name = require('./module.js').name; console.log(name); * 建立 02.html 文件,引入 src 中的 index.js 文件,但浏览器是无法运行的; * 此时,我们需要进行打包来解决两个问题:浏览器兼容和导入导出 js 文件的合并; * 使用打包命令,注意目录的问题,如果在根目录带上子目录路径; >> webpack ./02/src/index.js -o ./02/dist/bundle.js --mode=development * 只要打包入口文件即可,依赖的文件会自动合并; * development 表示开发模式,production 表示生产模式,压缩成一行; ## 4. 配置文件 ## * 打包一次的命令太过于冗长,且特别容易出错,所以要对这些路径参数进行存储; * 我们可以创建 package.json 文件,来配置 scripts 属性来部署生成路径; >> npm init -y // 生成配置文件命令 * 然后在 scripts 属性里添加子属性:build,属性值具体如下: "build" : "webpack ./02/src/index.js -o ./02/dist/bundle.js --mode=development" * 然后使用 npm 命令自动执行这个属性值的路径; >> npm run build * 如果是比较简单的打包,package.json 还行,当参数越发复杂维护将变得困难; * Webpack 还提供了一个 webpack.config.json 配置文件,解决这个问题; * 由于我们是子目录 01,02 这种,完全可以直接存放子目录中即可; * 也就是说,配置文件不一定非要存放在根目录,可以根据自己目录结构进行调整; /* * webpack 构建时,会自动读取此文件 */ // 获取当前路径 const path = require('path'); module.exports = { // 入口文件 entry: './src/index.js', // 出口文件 output: { // 文件名 filename : 'bundle.js', // 路径,要绝对路径 path : path.resolve(__dirname, './dist') }, // 生成模式 mode : "development" }; * 在哪个目录,就进入哪个目录,直接执行命名:webpack,即执行打包; ## 5. DevServer ## ### 问题需求 ### * 由于代码可能有 CommonJS 等非浏览器支持的语法,每次都必须打包才行运行; * 虽然借助 Webstorm 等工具可以构建服务器环境,但实际上不能时时监控刷新; * IDE 提供的服务器之间访问的是打包后的文件,是否监听时时刷新看个人习惯; * 以上:如果要方便的话,开发者需求的想法是,开发时方便调试,最后再打包; * 所以,官方提供了 Webpack-dev-Server 工具来解决这个问题,支持特性: (1) 支持 HTTP 服务访问:localhost,127.0.0.1 这种; (2) 监听变化时时刷新网页,时时预览; (3) 支持 Source Map; ### 安装部署 ### * DevServer 只要安装到本地即可使用,命令如下: >> npm i webpack-dev-server -D 在应用根目录安装,package.json 会自动添加 webpack-dev-server 版本号; * 由于课件是按照 01,02 这样目录构建的,你自己测试完全可以在根目录下; * 当然,根目录和子目录在部分操作上可能有路径问题,自行调试几次; * 运行 DevServer 时,由于我们在 03 这个子目录中,所以,我们要进入: >> cd 03 * 在 webpack.config.js 配置一些最基本的参数,方便运行; // devServer 自动化 devServer: { publicPath : '/dist', // 访问路径 port : 3000, // 独立端口 stats: 'minimal', // 迷你型服务启动信息 }, * 本地我们可以删除 dist 目录,还原打包之前再启动 devServer,测试效果; * 此时我们可以发现并不需要打包到本地,它是自动打包到内存让你时时预览调试的; * 也就是说:调试阶段,可以用 devServer,完成了,再最终打包到本地即可; * 我们可以在子目录生成一个 package.json 文件,在 scripts 设置 dev 属性; "dev" : "webpack-dev-server" >> npm run dev * 目前这个版本,火狐还是会有断开服务器的提醒,不过完全不影响我们调试; * 如果强迫症的同学,有两种解决方案: (1) 注释掉输出的错误信息,或者把错误提醒改成信息提醒; (2) 或者在 devServer 设置错误级别: clientLogLevel : 'none' 还有火狐还会出现 sockjs.js.map 的警告,可以设置 devTool 解决; devtool: 'source-map', 以上问题,谷歌浏览器均不存在! ## 6. Plugin 部署 Html ## ### 问题需求 ### * 目前为止,我们只能打包 js 文件模块,事实上:Html 文件也需要打包到一起; * 也就是说,我们需要把.js 和.html 文件都要打包到 dist 目录中去; * 那么 src 目录也应该存放相应的.html 文件,之前放在外面是方便测试; * 如果我们设定.html 名称为 index.html,放入 src,那如何连接.js 文件呢? * 预想,如果会打包到 dist,那么直接路劲:src=“bundle.js”; * 可以这样,调试的时候,路径又会产生问题?那这些问题,都直接交给插件处理吧! ### 安装部署 ### * 首先,安装 html-webpack-plugin 插件,本地安装即可; >> npm i html-webpack-plugin -D * 安装好后,可以在 package.json 中看到版本号; * 我们删除掉 src 外面的.html 文件,在 src 建立 index.html 文件,用于打包; * 我们并不需要在.html 文件中使用 // html 插件 const HtmlWebpackPlugin = require('html-webpack-plugin'); // 插件 plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html", // 值为默认值,源文件 filename: "index.html" // 值为默认值,打包生成的文件名 }) ], // devServer,publicPath 可以忽略 devServer: { // publicPath : '/dist', port : 3000, stats : "minimal", }, * 经过上述的一系列操作,解决了两个问题,打包后引入.js 文件,会自动引入; * 在使用 DevServer 时,localhost:3000 直接访问的就是 index.html; * 如果想要.html 和.js 打包后存在不同目录,可设置,并会自动链接; filename : 'js/bundle.js', filename: "html/index.html" <script src="../js/bundle.js"></script> * 打包后,上节课的 source map 生成了一个.map,这个在火狐刷新会引起弹窗; * 只要使用 inline-source-map,不生成文件,在最后生成一行文本即可; ## 7. Loader 打包 CSS ## ### 问题需求 ### * 通过之前的学习,我们知道如何打包 js 模块和 html 页面,并融合; * 还有一种东西需要处理,就是 css 样式以及 less、sass 等预处理样式; * 思路也是一样的,调试的时候可以试试监听,打包的时候也能融合; * 这里需要使用 module 这个属性,并需要安装使用以下三种插件: (1) css-loader:读取和编译 css 文件,转换为样式字符模块; (2) style-loader:将 css 插入到 JavaScript 中; (3) less-loader:读取和编译 less 预处理样式,转换为 css 文件; ### 安装部署 ### * 首先,我们先创建两个基本的 css 文件,另一个引入其中一个; /* font.css */ h1 { color: blue; font-size: 200px; } /* base.css */ @import "font.css"; body { background-color: gray; } * 和打包 html 文件一样,css 文件并不需要你手动去 link 引入,让插件处理; * 然后在.js 文件中,把.css 文件通过 require 引入进来; require('./base.css'); * 安装所需的 css-loader 插件和 style-loader 插件; >> npm i css-loader -D >> npm i style-loader -D * 安装完成后,可以在 package.json 检查版本号,确认已安装; * 在 webpack.config.js 中,使用 module 进行 css 文件部署工作; // 模块 module: { // 规则 rules: [ { // 规则获取需要部署的文件后缀 test: /\.css$/, // style-loader 将 css 字符串插入到 javascript // 通过浏览器工具样式被动态插入到<style>标签内 // css-loader 将 css 文件编译成字符串给 style-loader 处理 // 所以,这里数组的执行顺序是从右到左执行,否则失败; use : ['style-loader','css-loader'] }, ] }, * 还有一种 css 编码方式是:预处理样式,比如 Less,sass 等; * 首先创建一个 less.less 预处理样式文件,代码 css 一样即可,然后引入; require('./less.less'); * 我们这里简单使用一下 Less 先做一个基础了解,先安装 less-loader; >> npm i less-loader -D { test: /\.less$/, // less-loader 会先将.less 文件转换为.css 文件,然后再向左边处理 use : ['style-loader', 'css-loader', 'less-loader'] } ## 8. Loader 打包图片文件 ## ### 打包思路 ### * 我们继续打包文件:图片文件,分为 css 引入图片和 html 插入图片; * 如果是 css 加载图片,都是背景图,总所周知小图片采用 base64 转换字符串; * 而大图片和 html 插图图片,则都需要单独的 loader 插件来完成; * 本节课用到的 loader 插件如下: (1) file-loader:解析 JavaScipt 和 css 插入的图片; (2) url-loader:将图片转换为 base64 编码字符串; (3) html-loader:将.html 进行打包,从而解析 img 插入问题; ### 安装部署 ### * 首先,先研究第一个插件:file-loader,安装并配置; >> npm i file-loader -D { test: /\.(png|jpg|gif)/, use : ['file-loader'] } #loading { width: 780px; height: 422px; background-image: url("./loading.gif"); } #ts { width: 609px; height: 609px; background-image: url("./ts.png"); } * 也可以在.js 文件引入图片,会被自动解析; const img = require('./ts.png'); console.log(img); * 现在,我们要扩展这个插件内容,要求自定义目录和名称: { test: /\.(png|jpg|gif)/, loader: 'file-loader', // 加载一个 loader options: { name : './img/[name].[ext]', // 写入 img 目录,且按原名和后缀, } }, * 第二个插件,我们限定小于 10kb 的,直接用 base64 编码保存图片; * 具体为何要用这么做:扩展要探讨很多,直接搜索相关关键字了解; * 总结就是一句话:小图片用 base64 性比价收益最高,反之一样; >> npm i url-loader -D { test: /\.(png|jpg|gif)$/, // 这里使用 url-loader,它依赖 file-loader // 通过先判断图片大小,小的采用 base64,大的采用 file-loader loader: 'url-loader', options: { limit : 10240, // 限定 10kg 一下采用 base64 编码, name : './img/[name].[ext]' } }, * 第三种,就是插入到 html 的图片,需要使用 html-loader 进行解析; >> npm i html-loader -D { test: /\.html$/, use : ['html-loader'] //自动交给 url-loader 处理 }, ## 9. 分离 CSS 分类打包 ## * 虽然之前我们使用 style-loader 和 css-loader 进行打包; * 但这种打包是融入到.js 里面最终生成的,并不是独立的.css 文件; * 之前使用了 html 插件进行.html 打包,这次使用 css 打包的插件为: >> npm i mini-css-extract-plugin -D // 获取 css 插件 const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // 插件 plugins: [ new MiniCssExtractPlugin({ filename : './css/[name].css', }) ], use : [ { loader : MiniCssExtractPlugin.loader, options: { publicPath : '../' } }, 'css-loader' ] * 这样配置,路径就全部正确了。如果有强迫症,可以去掉./js 和./css 中的./; * 还有一种方式,就是直接使用 publicPath,加上 域名/img、域名/js、域名/css; http://127.0.0.1/img/xxx.jpg // 绝对路径,一劳永逸 * 使用 域名/img 这种模式,方便把 img,js,css 等静态资源部署到 cdn 上; * 也可以设置开发 src 和 dist 目录结构保持相同,这样更加清晰; ## 10. PostCss 兼容性转换 ## ### 兼容处理 ### * CSS 尤其是很多 CSS3,在部分浏览器是有兼容处理的,需要进行设置; * 可以使用 postcss-loader 来实现 CSS 语法的兼容性处理; >> npm i postcss-loader -D // 放在最右边 use : [ ... 'postcss-loader' ] * 单有 postcss-loader 还不行,需要搭配创建 autoprefixer 插件转换; >> npm i autoprefixer -D * 单有 postcss-loader 还不行,需要搭配创建 autoprefixer 插件转换; * 这个插件会在需要兼容性的样式加上 CSS 前缀,比如:-ms、-webkit 等; * 我们在 base.css 和 font.css(被@import 导入),增加需要兼容的 css; display: flex; transform: rotateY(130deg); * 在当前目录创建 postcss.config.js,用来配置兼容的浏览器; const AutoPreFixer = require('autoprefixer'); module.exports = { plugins: [ new AutoPreFixer({ overrideBrowserslist : [ '> 0.15% in CN' //可以写多个列表 ] }) ] } { //由于采用了@import,被导入的 css 无法解析,需要设置 importLoaders=1 即可 loader : 'css-loader', options: { importLoaders: 1 } } * 下图就是配置浏览器的语法,可以自行添加; ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2dvbmd4aWZhY2FpX2JlbGlldmU_size_16_color_FFFFFF_t_70_pic_center 1][] ### CSS4 代码 ### * 除了兼容浏览器之外,还可以通过 postcss-preset-env 实现 CSS4 代码兼容; >> npm i postcss-preset-env -D :root: { --green : green; }; h1 { color : var(--green); } // 请注意:如果使用 postcss-preset-env,就删除 autoprefixer // 因为 post-preset-env 集成了 autoprefixer,不需要再引入设置 const PostPresetEnv= require('postcss-preset-env); module.exports = { plugins: [ new PostPresetEnv({ browsers : [ '> 0.15% in CN' ] }), ] } ## 11. Babel 转换 ES6 语法 ## * 我们有时需要将 ES6+的语法转换成 ES5,让兼容性更好一些; * 这时需要有三个模块需要安装,具体如下: (1) babel-loader:与 Webpack 协同工作的模块,加载处理 js 文件; (2) @babel/core:Babel 编译器的核心模块,是 babel-loader 依赖; (3) @babel/preset-env:Babel 预置器,用于分析 ES6 语法; * 我们安装上述三个模块,然后进行配置,具体方法如下: >> npm i babel-loader @babel/core @babel/preset-env -D { test : /\.js$/, loader: 'babel-loader', options: { presets : [ '@babel/preset-env' ] } } * 我们在 src 中的 js 文件,使用 ES6 的箭头函数来尝试一下; let fn = (x, y) => x + y; console.log(fn(10, 20)); * 在没有使用 Babel 时,它打包会原封不动的使用 ES6 语法; * 在使用 Babel 之后,编译后的代码如下: var fn = function fn(x, y) { return x + y; }; console.log(fn(10, 20)); * 如果你使用了未纳入标准(提案中)的代码,打包时,它会提醒你安装相关插件; // 提案中,尚未纳入标准的语法 class Person { #name; constructor() { this.#name = 'Mr.Lee'; } } >> npm i @babel/plugin-proposal-class-properties -D options: { presets : [ '@babel/preset-env' ], plugins : [ '@babel/plugin-proposal-class-properties' ] } ## 12. ESLint 校验 JS 代码 ## * 基本的 ESLint 实现,需要一下安装以下模块: (1) eslint:JS 代码检查工具核心模块; (2) eslint-loader:webpack 协同模块; * 首先,先安装 eslint,然后安装配置信息; >> npm i eslint -D // 安装 eslint >> eslint --init // 安装配置信息 * 期间会让你选择配置信息情况,根据你实际情况选择即可,生成:.eslintrc.json; * 网上也会别人生成的配置信息可以拿来用,也可以去官网 eslint.cn/demo 生成信息; * 再次,我们安装 eslint-loader 模块; >> npm i eslint-loader -D * 最后,我们来配置 webpack.config.js; { test : /.js$/, loader: 'eslint-loader', // 编译前执行 enforce: 'pre', // 不检查的目录 exclude: /node_modules/ }, * 防止错误飘红太多,干扰演示,我们注释掉大部分代码,写上示例; var foo = bar; * 测试打包和预览提示校验; ## 13. 多页面配置打包 ## * 如果我们想生成多个.html 文件,比如 index.html 和 main.html; * 此时,我们需要修改一下入口文件和出口文件; // 入口文件 entry: { // 把需要加载的 js 以键值对方 index : './src/js/index.js', main : './src/js/main.js' }, 或 // 入口文件,也支持 ES6 的箭头函数 entry: () => ({ index : './src/js/index.js', main : './src/js/main.js' }), * 出口文件,需要按照入口文件的名称进行打包,否则只会打包一个; // 出口文件 output: { // 文件名 filename : 'js/[name].js', }), * 最后,我们要使用 HtmlWebpackPlugin 插件来设置自己想要的打包方案; // 插件 plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html", // 默认值 filename: "index.html", // 默认值 chunks: ['index', 'main'] }), new HtmlWebpackPlugin({ template: "./src/main.html", filename: "main.html", chunks: ['main'] }), ], ## 14. 压缩 Html 和 Css 代码 ## * 为何要压缩代码?什么情况下要压缩?答:在生产环境下打包时节约资源; * 既然在生产环境,那首先要把打包的配置更改为生产环境; // 生成模式 mode : "production", * 调节为生产环境打包,就会自动将 js 代码进行打包,不需要单独设置; * 对于 Html 文件打包,通过 HtmlWebpackPlugin 插件,生成环境会自动压缩; * 如果在开发环境中压缩,可以通过配置来设置要压缩的选项: minify: { collapseWhitespace: true, // 是否去除空格,默认 false removeComments: true, // 是否移除注释 默认 false }, * 对于 CSS 文件,就算设置了生成环境,它也不会自动压缩,此时需要另外设置; >> npm i optimize-css-assets-webpack-plugin -D // 获取 css 压缩插件 const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin') // 插件 plugins: [ new OptimizeCssAssetsWebpackPlugin(), // 压缩 css ], ## 15. 打包 Ts 和 Scss ## ### Scss ### * 和 Less 一样,Scss 也是 Sass 的一种使用较多的语法; >> cnpm install sass sass-loader node-sass -D * 由于这次我备课时,npm 连不上,故改成 cnpm; * 具体配置基本和 Less 一样,先创建.scss 文件,并引入; { test: /\.scss$/, // 从右向左执行 use : [ MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader' ] }, ### TypeScript ### * 越来越流行的 TypeScript,JavaScript 的一个超集; >> cnpm i typescript ts-loader -D { test: /\.ts$/, use : 'ts-loader', }, * 编写一个.ts 文件,然后通过 import 导入到 index.js; // type.ts export const output = (content : string) => { return content } // import ts import { output } from './type.ts' console.log(output('Mr.Lee')) * 如果要省略掉 import 中文件后缀,需要配置; module.exports = { resolve: { extensions: ['.ts', '.js'] }, } * 需要创建 tsconfig.json 文件; ## 16. Resolve 模块解析 ## * 上节我们使用了 typescript,在 import 不限定后缀会出现无法载入; * 所以,我们使用了 Resolve 模块解析的中 extensions 来进行配置; // 模块解析 resolve: { // 导入文件查找的限定后缀,默认.js 和.json extensions: ['.ts', '.js', '.json' ] }, * 导入语句是如果检测不到指定的会报错; * alias 配置可以用别名的方式,将导入路径映射成一个新的路径; // 设置一个别名路径(绝对路径) alias: { css : path.resolve(__dirname, './src/css') } require('css/base.css'); * modules 配置可以指定 webpack 的解析模块目录; // 找到解析模块目录,如果当前找不到就不断往上一层找 modules: ['node_modules'] // 也可以设置指定目录直接查找,检查查找次数 modules: [path.resolve(__dirname, '../node_modules')] * 自然,也可以设置第二参数,防止第一参数找不到报错; ## 17. Source-Map 配置 ## * Source-map 可以将编译、打包、压缩后的代码映射到源代码上; * 比如你打包或运行的代码是编译后的,报错后,它能指向你源代码的位置上; // 会生成一个.map 文件 devtool: 'source-map', * 根据不同的方式,有下面几种类型: source-map // 打包后会生成一个对应的.map 文件 inline-source-map // 打包后会在 js 文件的内部最后生成 map 内容 eval-source-map // 打包后会在每个模块都执行 eval hidden-source-map // 打包后会生成.map 文件但不会追踪原始文件的错误代码 cheap-source-map // 打包后会生成.map 并只能精确到行 * 以上打包还可以合并比如 eval-cheap-source-map * 在开发环境和生产环境,我们该如何选择?开发要求速度快,调试方便推荐: eval-source-map 或 eval-cheap-source-map // 开发环境 source-map // 生产环境 ## 18. watch 监听和 clean 清理 ## ### watch 监听 ### * 每次打包,都比较烦,耗时耗力,有一种解决方案:watch 文件监听; * 这种解决方案,就是你打包时,就挂着监听你原始文件的变化,从而自动更新; // 文件监听,默认 false watch: true, // 开启 watch,下面才有意义 watchOptions: { // 不监听解析模块目录 ignored: /node_modules/, // 防止更新频率太快,默认 300 毫秒,意味监听到变化后 500 毫秒再编译 aggregateTimeout: 500, // 轮询间隔时间,1 秒,询问系统指定文件是否变化了 poll: 1000 }, ### clean 清理 ### * 每次打包,都要手动删除,因为不删除的话,改了配置目录就会多出废目录或文件; * 所以,使用 clean-webpack-plugin 插件,来处理这个问题; >> npm i clean-webpack-plugin -D // 获取 clean 清理插件 const { CleanWebpackPlugin } = require('clean-webpack-plugin') // 插件 plugins: [ new CleanWebpackPlugin() ] ## 19. HMR 热替换 ## * 首先,页面调试有一个问题,就是当我们编辑了 css 或 js,它会自动刷新; * 但如果有大量的 css 或 js,一个小修改,就要全部刷新,影响开发性能; * 而 HMR 热替换就是解决这个问题,当 css 或 js 修改时,只刷新修改的部分; * 对于 html 文件,不需要热替换,就一个文件; * 开启 HMR 热替换,可以在启动服务时加上–hot,或者在 devServer 配置; devServer: { hot : true }, * 对于 css 的热替换,需要使用 style-loader ,而现在被抽离 css 插件替换了; * 所以,我们先要注释掉这个插件,改为 style-loader ; test: /\.scss$/, //从右向左执行 use : [ // MiniCssExtractPlugin.loader, 'style-loader', 'css-loader', 'sass-loader' ] * 当开启了 HMR 热替换之后,发现 html 文件修改后无法自动更新了; * 此时,我们需要在入口文件加入这个 html 文件,即可; entry: [ './src/js/index.js', './src/index.html' ], * 对于 js 的热替换,只要在入口文件,对加载的其它 js 文件进行设置即可; import name from './module' console.log(name) if (module.hot) { module.hot.accept('./module', () => { console.log(name) }) } ## 20. Axios 跨域请求 ## * 这里提供两个远程 json 文件,会返回一些数据用于测试跨域问题; https://cdn.liyanhui.com/data.json (可跨域,设置过) https://cdn.ycku.com/data.json (不可跨域,默认) * 安装 axios,用于 ajax 测试; >> npm install axios * 编写代码,测试数据; import axios from 'axios' axios.get('https://cdn.liyanhui.com/data.json').then(res => { console.log(res.data) }) * 如果把地址中的 liyanhui 换成 ycku 的话,会出现跨域的问题; * 通过 devServer 设置代理模式,来解决跨域问题; devServer: { // 设置代理 proxy : { // 匹配前缀为/api '/api' : { // 目标域名 ip target : 'https://cdn.ycku.com', // 改变源 changeOrigin : true, // 重写 url, 去掉 /api pathRewrite : { '^/api' : '' } } } }, axios.get('/api/data.json').then(res => { ... ## 21. 环境分离设置 ## * 当配置文件写的越发繁杂时,发现生产环境的配置和开发环境配置有冲突; * 此时,我们希望有两套配置文件,一套用于开发环境,一套用于生产环境; * 这里使用 js 合并插件 webpack-merge 来实现配置文件的分离保存; * 我们创建另外两个 dev.config.js(开发) 和 prod.config.js(生产) ; * 将原先的 webpack.config.js 改为 base.config.js ,然后分离代码; >> npm i webpack-merge -D // 合并 js 插件 const { merge} = require('webpack-merge') // 基础配置 const base = require('./base.config') // 开发环境配置 module.exports = merge(base, { .... } * 分离好了之后,我们需要修改 package.json,把默认的配置启动和打包更改了; "dev": "webpack-dev-server --config dev.config.js", "build" : "webpack --config prod.config.js" * 打包命名更改为 npm run build 即可;其它不变; ## 22. 打包优化和 dist 服务 ## ### 打包优化 ### * webpack 提供了一个选项:optimiztion 来帮助我们优化; * 只不过开启了生产环境,就自动开启了压缩,除了 css 需要我们自己弄; * 我们使用自带的 Terser-webpack-plugin 插件来设置自己的压缩选项; // 打包优化插件 const TerserWebpackPlugin = require('terser-webpack-plugin') // 优化 optimization : { // 如果是生成模式,自动为 true // minimize : true, // 配置 TW 插件 minimizer : [new TerserWebpackPlugin({ // 是否开启缓存,开启缓存加速 cache : false, // 插件选项 terserOptions : { // 压缩方式 compress : { // 剔除无用代码 unused : true, // 剔除死代码 dead_code : true, // 剔除 console.log drop_console : true, // 剔除 debugger drop_debugger : true, } } })] }, ### dist 服务 ### * 打包后,我们想要在静态服务器上测试,先要安装静态服务器; >> npm i serve -g // 安装 >> serve dist -s // 运行 dist 目录 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2dvbmd4aWZhY2FpX2JlbGlldmU_size_16_color_FFFFFF_t_70_pic_center]: /images/20221123/082abdcd153e433e8b93870b6bf8c831.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2dvbmd4aWZhY2FpX2JlbGlldmU_size_16_color_FFFFFF_t_70_pic_center 1]: /images/20221123/96b8c424e7484ca3ba9458c17c8f1aca.png
还没有评论,来说两句吧...