1. Webpack 简介
- Webpack 是一个现代 JavaScript 的静态模块打包器(module bundler);
- 那为什么要用这种构建工具进行打包呢?答:解决模块依赖和兼容性;
- 打包器(构建工具)会将所有依赖关系按照规则合并为单个 JS 文件,一次加载;
- 最终,生成浏览器能够使用的静态资源,下图为官方宣传效果图:
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
- 有时 npm 命令不太稳定,报错的话,可以使用 cnpm,语法一模一样;
>> npm install -g cnpm --registry=https://registry.npm.taobao
- 安装好 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
}
}
- 下图就是配置浏览器的语法,可以自行添加;
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/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/data.json (可跨域,设置过)
https://cdn.ycku/data.json (不可跨域,默认) - 安装 axios,用于 ajax 测试;
>> npm install axios
- 编写代码,测试数据;
import axios from 'axios'
axios.get('https://cdn.liyanhui/data.json').then(res => {
console.log(res.data)
})
- 如果把地址中的 liyanhui 换成 ycku 的话,会出现跨域的问题;
- 通过 devServer 设置代理模式,来解决跨域问题;
devServer: {
// 设置代理
proxy : {
// 匹配前缀为/api
'/api' : {
// 目标域名 ip
target : 'https://cdn.ycku',
// 改变源
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 目录
更多推荐
【Webpack】模块打包工具 Webpack 的各种使用方式
发布评论