webpack 和 babel
read more about this https://www.imooc.com/article/287156
1:为什么需要使用 webpack打包 和 babel进行转译 ?
- ES6 模块化,浏览器暂不支持
- ES6 语法,浏览器并不完全支持
- 压缩代码,整合体积,让网页加载更快
2:webpck
-
简介:它是一个前端模块打包工具,主要由entry,output,loader,plugins四部分。它侧重于模块,例如它将css文件看作一个模块,通过css-loader将css打包成一个静态资源
-
工作原理:其核心价值就是前端源码的打包,即将前端源码中的每一个文件(无论任何类型),都当作一个 pack ,然后分析依赖,将其最终打包出上线运行的代码
-
核心部分:
entry 指示webpack应该使用哪个模块,来作为构建其内部依赖图的开始 output 告诉webpack在哪里输出它所创建的bundle,以及如何命名这些文件 loader 转换类型模块-webpack本身只能理解JavaScript和JSON文件,loader让webpack能够去处理其他类型文件,并将它们转换为有效模块 plugin 打包过程中各种自定义功能的插件,比如打包优化,资源管理,注入环境变量
-
webpack 的初始化和搭建
-
安装:npm install webpack
-
写入基本webpack打包配置语句
-
// path是Node.js的一个核心模块,用于操作文件路径
const path = require('path')
// common.js 的语法
module.exports = {
mode: 'development', // 分为 开发 和 发布('production')两种模式:development模式下打包代码不会被压缩,可调试
entry: path.join(__dirname, 'src','index.js' ), // 当前目录陆续拼接路径,最后找到整个文件的文件入口
output: {
filename: 'bundle.js', // 打包输出的文件名
path: path.join(__dirname, 'dist') // 打包输出文件放置的目录
}
}
-
安装:npm install html-webpack-plugin -D(webpack解析html的插件)+ npm install
webpack-dev-sever -D(可以启动服务的插件) -
继续写入webpack的配置语句
// 用 Node.js 的 path 模块:寻找当前目录文件的模块
const path = require('path')
// 将刚刚npm 下载的插件引入,进行一些配置
const HtmlWebpackPlugin = require('html-webpack-plugin')
// common.js 的语法
module.exports = {
mode: 'development', // 分为 开发 和 发布('production')两种模式:development模式下打包代码不会被压缩,可调试
entry: path.join(__dirname, 'src','index.js' ), // 当前目录陆续拼接路径,最后找到整个文件的文件入口
output: {
filename: 'bundle.js', // 打包输出的文件名
path: path.join(__dirname, 'dist') // 打包输出文件放置的目录
},
// 数组形式:可以配置多个插件
plugins: [
// 使用new操作符来创建这个插件实例
new HtmlWebpackPlugin({
template: path(__dirname,'src','index.html') ,
filename: 'index.html', // 产出的文件名(路径默认放在webpack统一配置的output路径下)
})
],
devSer: {
port: 3000, // 启动服务的端口
contenrBase: path.join(__dirname, 'dist') // 启动服务需要跑的文件位置
}
}
经过上面代码堆webpack的配置,可发现打包出来的代码依然是ES6 的代码,会存在部分浏览器不支持的情况,需要 babel 进行转译
3:babel
babel:是将ES6及以上版本的代码转换成ES5的编译工具(本身二者无联系,但是babel作为转译工具,可以提供插件帮助 webpack打包出更好代码的)
- 安装:npm install @babel/core @babel/preset-env babel-loader -D(@babel代表组,/ 后面代表具体模块;@babel/core @babel/preset-env 是babel的核心和配置集合,babel-loader 是提供给 webpack 的插件)
- 写入配置代码
// 新建的 .babelrc babel 配置文件
{
// 是个数组,可放置多项
"presets": [
// 刚刚下载的,放进配置里应用
"@babel/preset-env"
]
}
加入babel配置之后完整的 webpack 配置代码
// 用 Node.js 的 path 模块:寻找当前目录文件的模块
const path = require('path')
// 将刚刚npm 下载的插件引入,进行一些配置
const HtmlWebpackPlugin = require('html-webpack-plugin')
// common.js 的语法
module.exports = {
mode: 'development', // 分为 开发 和 发布('production')两种模式:development模式下打包代码不会被压缩,可调试
entry: path.join(__dirname, 'src','index.js' ), // 当前目录陆续拼接路径,最后找到整个文件的文件入口
output: {
filename: 'bundle.js', // 打包输出的文件名
path: path.join(__dirname, 'dist') // 打包输出文件放置的目录
},
// 不同模块去做不同解析
module: {
rules: [
{
test: / \.js$/, // 正则表达式:以 js 结尾的文件
loader: ['babel-loader'], // babel 提供给webpack使用的插件
include:path.join(__dirname, 'src'), // 包含哪些目录需要做 loader 操作
exclude: /node_modules/ // 除去哪些目录不进行该 loader 转译
}
]
},
// 数组形式:可以配置多个插件
plugins: [
new HtmlWebpackPlugin({
template: path(__dirname,'src','index.html') ,
filename: 'index.html', // 产出的文件名(路径默认放在webpack统一配置的output路径下)
})
],
devSer: {
port: 3000, // 启动本地服务的端口
contenrBase: path.join(__dirname, 'dist') // 启动服务需要跑的文件位置
}
}
其中,实际开发中,serve端提供的端口地址和前端可能不同,导致 ajax 受到跨域限制;使用 webpack 可配置代理,解决跨域问题:
devSer: {
port: 19012,
// 设置代理:
proxy: {
// 将本地 /api/xxx 代理到 https://192.168.5.47/api/xxx
'/api':{
target: 'https://192.168.5.47',
changeOrigin: true,
},
// 将本地 /api2/xxx 代理到 https://192.168.5.47/xxx
'/api2': {
target: 'https://192.168.5.47:38088',
changeOrigin: true,
pathRewrite: ''
},
}
关于 webpack 面试常见问题
1. 什么是 bundle,什么是 chunk,什么是 module?
答:bundle 是由 webpack 打包出来的文件;chunk (块)是指webpack 在进行模块化分析的时候,代码分割出来的代码(打包出来的代码块);module 是开发过程中的单个模块
2. 什么是 Loader ?什么是 Plugin ?(如上的 webpack核心四点也有提及)
答:Loader 是用来告诉webpack该如何处理转化某一类文件,并且引入到打包文件中;Plugin 是用来自定义webpack 打包过程的方式,一个插件是包含 apply 方法的一个对象,通过这个方法可以参与到整个 webpack 打包的各个流程
3:什么是Tree-shaking?
答:mode为production 时会默认压缩代码并进行其他优化,如 tree shaking:tree-shaking 指的是在打包过程中剔除掉引入但未使用的‘死代码’