Babel 和 Webpack
一. Babel
Babel 官网:https://babeljs.io/
Babel 在线编译:https://babeljs.io/repl
1. Babel 是什么
Babel 是 JavaScript 的编译器,使用 Babel 就可以使用下一时代的 js 语法
简单来说将 ES6 代码 -> ES5 代码
例子:
// ES6
const data = {
a: 100
}
const a = data?.a// ES5
"use strict";
const data = {
a: 100
};
const a = data === null || data === void 0 ? void 0 : data.a;注意:
- Babel 本身可以编译 ES6 的大部分语法,比如 let、 const、箭头函数、类
- 但是对于 ES6 新增的 API,比如 Set、Map、 Promise 等全局对象,以及一些定义在全局对象上的方法(比如 Object.assign / Array.from)都不能直接编译,需要借助其它的模块
- Babel 一般需要配合 Webpack 来编译模块语法
Babel 使用教程:https://babeljs.io/setup
常用使用方式:
- 在 CLI(命令行)中使用 Babel
- 在 Webpack 中使用 Babel
什么是 Node.js 和 npm
Node.js 是个平台或者工具,对应浏览器
后端的 JavaScript = ECMAScript + IO + File + ...等服务端的操作
npm:node 包管理工具 -> npm install ... 进行安装
安装 Node.js
shellnode -v # 查看 Node.js 版本 npm -v # 查看 npm 包管理工具版本初始化项目
shellnpm init注意:初始化项目时,name 不能为中文
安装 Babel 需要的包
shellnpm install --save-dev @babel/core @babel/cli注意:npm 安装特定版本包:npm install xxx@版本号
编译命令
首先在 package.json 中添加 "build": "babel src -d dist"
babel src -d dist --> babel 编译目录 --out-dir的缩写 输出目录
CLI 中使用:
shellnpm run buildBabel 配置文件
shellnpm install @babel/preset-env --save-dev包讲解:
json@babel/cli // 命令行工具 @babel/core // babel 核心包 - 负责调度 @babel/preset-env // babel 怎么转换语法新建 babel.config.json 文件,并配置
json{ "presets": ["@babel/preset-env"] }最后重新编译:
shellnpm run build
二. Webpack 入门
1. Webpack 是什么
认识 Webpack
webpack 是静态模块打包器。当 webpack 处理应用程序时,会将所有这些模块,打包成一个或者多个文件
理解 Webpack
模块:webpack 可以处理 js / css / 图片 / 图标字体 等单位
静态:开发过程中存于本地的 js / css / 图片 / 图标字体等文件 都是静态文件
动态内容:webpack 没办法处理,只能处理静态的
初始化项目
shellnpm init安装 webpack 需要的包
shellnpm install --save-dev webpack-cli webpack配置 webpack
新建 webpack.config.js 文件,并配置
jsconst path = require('path'); module.exports = { mode: 'development', // 打包模式,不写默认为 production 1.development 2.production 3.none entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' } };打包并测试
首先在 package.json 中添加
"webpack": "webpack --config webpack.config.js"js"scripts": { // 新增下面语句 "webpack": "webpack --config webpack.config.js" }webpack --config webpack.config.js --> webpack --config 指定 webpack 配置文件,若不写则默认寻找 webpack.config.js 文件
CLI 中使用
shellnpm run webpack
三. Webpack 的核心概念
entry 指定入口文件
jsmodule.exports = { // 单入口文件:等价下面 main 中写法 entry: './src/index.js' // 多入口文件 entry: { // main 可随意定义 main: './src/index.js', search: './src/search.js' } };output 出口文件
jsconst path = require('path'); module.exports = { // 单入口 output: { // output 必须使用绝对路径,所以要引入 path // __dirname 指当前文件的绝对路径,resolve 方法用于将 __dirname 和 dist 拼接 path: path.resolve(__dirname, 'dist'), // 打包后文件名 filename: 'bundle.js' } // 多入口 output: { path: path.resolve(__dirname, 'dist'), // [name] 为固定写法,值取自多入口定义的 key 值 filename: '[name].js' } };
什么是 loader
loader 让 webpack 能够处理非 js 文件的模块
babel-loader
将 webpack 和 babel 连同一起能使用的模块
安装:
shellnpm install --save-dev babel-loaderjsmodule.exports = { module: { rules: [ { // 正则 test: /\.m?js$/, // 排除文件(正则) exclude: /node_modules/, // 使用 babel-loader loader: "babel-loader" } ] } };babel-polyfill
babel 可编译 ES6 新增的 API
具体可参考:https://babeljs.io/docs/en/babel-polyfill
安装:
shellnpm install --save @babel/polyfill使用:
可在入口文件顶部或 webpack.config.js 顶部添加
jsrequire("@babel/polyfill");也可在 webpack 中配置(单入口文件使用)
jsentry: ["@babel/polyfill", "./src/index.js"]
什么是 plugins
插件可用于执行范围更广的应用
html-webpack-plugin
在 HTML 中自动引入 webpack 打包出来的 js,并复制到输出文件夹中
安装:
shellnpm install --save-dev html-webpack-plugin配置 html-webpack-plugin 插件
jsconst HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { plugins: [ // 单入口配置 new HtmlWebpackPlugin({ // 指定 html 模板文件(不写,会生成一个默认页面) template: './index.html' }) // 多入口配置 new HtmlWebpackPlugin({ template: './index.html', // 指定输出文件名 filename: "index.html", // 指定入口文件(entry 中的 key 值) chunks: ['index'], minify: { // 删除文档中的注释 removeComments: true, // 删除文档中的空格 collapseWhitespace: true, // 删除各种 html 标签属性值的双引号 removeAttributeQuotes: true } }), new HtmlWebpackPlugin({ template: './search.html', filename: "search.html", chunks: ['search'] }) ] }
四. Webpack 的应用
1. 处理 CSS 文件
css-loader
让 webpack 识别 js 中引入 css 模块
安装:
shellnpm install --save-dev css-loader配置 css-loader
jsmodule.exports = { module: { rules: [{ test: /\.css$/, loader: "css-loader" }] } }style-loader
将引入的 css 模块,通过 style 内部样式的方式嵌入到 HTML 中
安装:
shellnpm install --save-dev style-loader配置 style-loader
jsmodule.exports = { module: { rules: [{ test: /\.css$/, // 此处同时配置多个 loader 时,需使用 use // use 可为对象,可为数组。注意:当为数组时,加载顺序为从右向左 // loader: "css-loader", use: ['style-loader', 'css-loader'] // 注意顺序,从右向左加载 }] } }mini-css-extract-plugin
将引入的 css 模块,通过 link 外部样式的方式嵌入到 HTML 中
安装:
shellnpm install --save-dev mini-css-extract-plugin配置 mini-css-extract-plugin
jsconst MiniCssExtractPlugin = require("mini-css-extract-plugin") module.exports = { module: { rules: [{ test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'] // 注意顺序,从右向左加载 }] }, plugins: [ new MiniCssExtractPlugin({ filename: "css/[name].css", }) ] }
2. 使用 file-loader 处理 CSS 中的图片
如果是外部图片资源,是不需要考虑 webpack 的,只有本地图片资源才需要被 webpack 处理
在 webpack5 中 已经弃用 file-loader 和 url-loader,下面内容仅供学习 webpack 做参考
且最新版本中的 css-loader 已经新增本地图片的加载器(不支持图片命名)
如需在 webpack5 中正确使用 file-loader 需参考下面配置
jsmodule.exports = { module: { rules: [{ test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'] }, { test: /\.(png|jpg|gif)$/, use: [{ loader: "file-loader", options: { // file-loader 默认采用ES模块语法,即import './'的形式 // 如果想使用 commonjs 规范的话 则需要配置下项 esModule: false } }], type: "javascript/auto" // 使用 file-loader 加载本地图片 }] } }具体其他内容可参考:
file-loader
让 webpack 识别本地中的 其他类型文件 模块
安装:
shellnpm install --save-dev file-loaderfile-loader 配置
jsconst MiniCssExtractPlugin = require("mini-css-extract-plugin") module.exports = { module: { rules: [{ test: /\.css$/, // 因为使用了 mini-css-extract-plugin 插件 // 可能导致打包出来的 css 引入图片路径有问题 use: [{ loader: MiniCssExtractPlugin.loader, options: { // 需要配置 mini-css-extract-plugin 插件的公共路径(新版本中可以不用配置) publicPath: '../' } }, 'css-loader'] }, { test: /\.(png|jpg|gif)$/, use: [{ loader: "file-loader", options: { // 配置 file-loader 将本地图片统一放到指定路径下 // ext -> 原本后缀 name: 'img/[name].[ext]', esModule: false } }], type: "javascript/auto" }] }, plugins: [ new MiniCssExtractPlugin({ filename: "css/[name].css", }) ] }
3. 使用 html-withimg-loader 处理 HTML 中的图片
html-withimg-loader
让 webpack 识别 HTML 中的本地图片
安装:
shellnpm install --save-dev html-withimg-loaderhtml-withimg-loader 配置
jsmodule.exports = { module: { rules: [{ test: /\.(png|jpg|gif)$/, use: [{ loader: "file-loader", options: { name: 'img/[name].[ext]', // 此处配合 html-withimg-loader 关闭 ES6 模块化导出模式 esModule: false } }], type: "javascript/auto" }, { test: /\.(html|htm)$/, loader: "html-withimg-loader" }] } }
4. 使用 file-loader 处理 JS 中的图片
配置与 file-loader 配置相同
jsimport img from './img/logo.png' console.log(img) // 此处为打包后 dist 文件夹中的路径,而不是上面引入时的路径(/img/logo.png) const imgElement = document.createElement('img') imgElement.src = img document.body.appendChild(imgElement)
5. 使用 url-loader 处理图片
url-loader
比 file-loader 更全面,底层为 file-loader 部分功能
安装:
shellnpm install --save-dev url-loaderurl-loader 配置(注意点同 file-loader,可能被弃用)
jsmodule.exports = { module: { rules: [{ test: /\.(png|jpg|gif)$/, use: [{ loader: "url-loader", options: { name: 'img/[name].[ext]', esModule: false, limit: 10000 // 限制 10k 大小以下图片会被转成 base64 } }], type: "javascript/auto" }] } }
6. 使用 webpack-dev-server 搭建开发环境
安装
shellnpm install --save-dev webpack-dev-server在 package.json 中配置
json"scripts": { "build": "webpack", // 新增下面语句,添加 --open 参数则会打开默认浏览器 "dev": "webpack-dev-server --open" }其他配置内容请参考
devServer