1. 构建工具
- 当我们习惯了在node中编写代码的方式后,在回到前端编写html、css、js这些东西会感觉到各种的不便。比如:不能放心的使用模块化规范(浏览器兼容性问题)、即使可以使用模块化规范也会面临模块过多时的加载问题。
- 我们就迫切的希望有一款工具可以对代码进行打包,将多个模块打包成一个文件。这样一来即解决了兼容性问题,又解决了模块过多的问题。
- 构建工具就起到这样一个作用,通过构建工具可以将使用ESM规范编写的代码转换为旧的JS语法,这样可以使得所有的浏览器都可以支持代码。
ESM模块 --> webpack/vite --> 原始js代码
2. webpack
2.1 webpack 使用
- 因为是在node 环境中运行,所以先初始化项目
npm init -y
- 安装依赖
webpack
webpack-cli
(使用命令行运行webpack)
npm i -D webpack
npm i -D webpack-cli
-D 表示在生产时使用
- 在项目中创建src目录,然后编写代码(index.js)
- 在命令行执行
npx webpack
使用模块化时,在node / webpack 环境中js/json 后缀不需要写,会自动补全;但是原生js 代码需要写上,不然会出现文件找不到的情况。
2.2 webpack 配置文件
- 在根目录中创建
webpack.config.js
注意:此处文件是webpack的配置文件,webpack是在node 环境中运行的,所以需要使用CommonJS
module.exports = {// output: {// path: path.resolve(__dirname, 'dist'),// filename: 'main.js'// },mode: "development" // 设置mode production:生产模式 development:开发模式
}
webpack 只会打包会执行的代码,只有定义但没被调用的变量或者函数等数据不会被打包
webpack官网
( 1 ) entry – 入口文件
module.exports = {entry: './src/index.js', // 入口文件 默认打包./src/index.js// entry: "[./src/index.js, './src/index2.js']" // entry:{// a:"./src/index.js"// b:"./src/index2.js"// }// 也可以打包多个文件}
( 2 ) ouput – 出口文件
module.exports = {
output: {path: path.resolve(__dirname, 'dist'), // 指定打包目录 必须是绝对路径filename: 'main.js', // 指定打包文件名// filename: "[name].js" name值得是上面的a,b// filename: "[name]-[id]-[hash].js" 打包后的文件名上带有id ,hash值clean: true // 自动清理打包目录(比如dist)},
}
( 3 ) loader – 加载器
module.exports = {module: {// 一个规则只负责一个功能rules: [{// 这个规则只负责打包css代码// 匹配文件需要使用正则表达式test: /\.css$/i, // 匹配以css结尾的文件use: "css-loader"},{// 这个规则负责打包和转换css代码test: /\.css$/i, // 匹配以css结尾的文件use: ["style-loader","css-loader"] // 注意书写顺序 loder 从后往前执行 这里需要安装依赖 npm i style-loader css-loader -D},{// 引入图片test: /\.(jpg|gif|png)/i,type: "asset/resource" // 图片类型的资源不需要安装依赖}]}
}
( 4 ) babel – (转换js语法)
在打包文件时webpack会把一些不必要的函数以及变量省略,比如下面就将常量和自执行的函数省略部分:
省略前:
document.body.insertAdjacentHTML("beforeend","<hl>今天天气真不错,风才12级k/h1>")
const a=10
const fn =()=>{
return "哈哈"
}
console.log(a)
console.log(fn())
document.body.onclick =()=>{
alert("你点我干嘛!")
}
省略后:
document.body.insertAdjacentHTML("beforeend","<hl>今天天气真不错,风才12级k/h1>")
console.log(10)
console.log("哈哈")
document.body.onclick =()=>{
alert("你点我干嘛!")
}
注意:在低版本浏览器中不兼容箭头函数等其他的新特性,但是我们现在希望能够使用新的特性,我们可以采用折中的方案。依然使用新特性编写代码,但是代码编写完成时我们可以通过一些工具将新代码转换为旧代码。例如babel
–将新JS语法转换为旧的js代码
babel
用来转换代码,是一个loder。
使用时需要:
- 安装
npm i -D babel-loader @babel/core @babel/preset-env
- 配置
{test: /\.(?:js|mjs|cjs)$/,exclude: /node_modules/,use: {loader: 'babel-loader',options: {presets: [['@babel/preset-env', { targets: "defaults" }]]}}}
指定兼容浏览器:
在package.json 文件中添加以下内容:
"browserlist": ["defaults", // 默认配置"ie 6-8" // 指定配置]
2.3 插件
插件 – 为webpack 扩展功能
html-webpack-plugin ------ 在打包代码后,自动在打包目录生成html页面
- 安装依赖
npm i -D html-webpack-plugin
- 配置
plugins: [new HtmlPlugin({template: './src/index.html'}),]
插件和加载器区别:
加载器会对代码进行处理,插件只做辅助工作。
2.4 webpack 开发服务器
每次修改完代码之后都需要手动输入命令进行代码打包,以下两种方法可以改善这种情况。
npx webpack --watch
- 安装依赖
npm i -D webpack-dev-server
npx webpack serve
npx webpack serve (–open) 在浏览器中打开网页
2.5 sourceMap
注意:使用 npx webpack serve (–open) 时只会j将打包好的文件放在服务器上,自己本身的文件中是没有dist文件夹的。
开发模式(development)打包之后的代码可以进行调试,但是生产模式(production)下打包的代码不可调试。
// 开发时要使用的工具devtool: "inline-source-map"
这样就达到执行打包后的代码,调试源码的效果。
3. Vite
- 相较于webpack,vite采用了不同的运行方式:
- 开发时,并不对代码打包,而是直接采用ESM的方式来运行项目
- 在项目部署时,在对项目进行打包
- 除了速度外,vite使用起来也更加方便
3.1 使用
- 安装依赖
npm i -D vite
直接在创建根目录下创建html文件,但是在引入js文件时必须表明type=“module”,因为此处使用的是ESM语法。
- 使用
npx vite
出现一个网址地点,即所对应的index.html 1️⃣
打包代码:
npx vite build
注意:
打包完的代码不能直接在浏览器打开,需要通过网址/服务器进行访问(live server也不可以);或者通过2️⃣
npx vite preview
1️⃣处打开的是开发服务器,代码变化那么页面内容也会随之改变;
但是2️⃣处打开的是进行预览,页面不会随代码改变而改变,需要重新打包后才会有变化。
3.2搭建一个vite 项目:
npm create vite
vanilla —> 原生js
vite的使用不需要配置loader去引入css等文件。
vite需要配置的地方:
浏览器对代码的兼容性
使用插件进行
同样的,在根目录下创建vite.config.js
npm add -D @vitejs/plugin-legacy
import legacy from '@vitejs/plugin-legacy'
import { defineConfig } from 'vite'
export default defineConfig({
plugins:[
legacy({
targets:['defaults','not IE 11']
})
]
})