续接上篇webpack入门
使用Babel处理ES6
目录结构如上:
如果你在index.js
中写了ES6的代码
const arr = [
new Promise(()=>{}),
new Promise(()=>{})
]
arr.map(item=>{
console.log(item)
})
npx webpack
打包后,打开打包后的main.js
你会发现,webpack并没有做任何处理,直接将ES6的语法打包了,此时你用谷歌浏览器打开,还是可以正常显示的,因为谷歌浏览器与时俱进,已经支持了ES6,但有些浏览器并不支持ES6。
于是我们希望webpack将ES6的代码转化成ES5的代码,再打包
https://www.babeljs.cn/setup#installation
babel官网对webpack的配置
安装依赖
npm install --save-dev babel-loader @babel/core @babel/preset-env
配置webpack.config.js
module:{
rules:[
{
test:/\.js$/,
exclude:/node_modules/,// 不用去处理node_modules中的js文件
loader:'babel-loader',
}
]
}
因为node_modules
安装包中,已经帮我们做了语法转换的处理,所以我们不需要再去转换他
npx webpack
运行命令后,main.js
对ES6的转换如下
可以发现,const被转换成了var,箭头函数被转换成了普通函数,但是Promise并没有被转换
翻译Promise等ES6的新方法
使用@babel/polyfill可以翻译Promise等新的语法
https://www.babeljs.cn/docs/babel-polyfill
babel官网
npm install --save @babel/polyfill
在index.js
文件中引入@babel/polyfill
import "@babel/polyfill"
const arr = [
new Promise(()=>{}),
new Promise(()=>{})
]
arr.map(item=>{
console.log(item)
})
再次运行命令npx webpack
接着你去看main.js
比之前多了400多kb,这些是实现Promise等所有高级语法的代码
这时候你会说,那可不可以按需加载,比如只是用到了Promise,那就加载实现Promise的代码就好了
答案是可以的
module:{
rules:[{
test:/\.js$/,
exclude:/node_modules/,
loader:'babel-loader',
options:{
presets:[['@babel/preset-env',{
useBuiltIns:'usage'
}]]
}
}]
}
npx webpack
执行命令后 main.js
果然缩小到了60多kb
Babel转化ES6的其他细节
如果我们希望根据浏览器的不同,来决定是不是使用
@babel/polyfill
因为有些浏览器已经支持es6就没必要再去转换了
//webpack.config.js
module.exports = {
module:{
rules:[
{
test:/\.js&/,
exclude:/node_modules/,
loader:'babel-loader',
options:{
presets:[['@babel/preset-env',{
targets:{
edge:"17",
firefox:"60",
chrome:"67",
safari":"11.1"
},
useBuiltIns:'usage'
}]]
}
}
]
}
}
npx webpack
运行命令后,你会发现main.js
缩小到了3.87kb,这大概是因为target中的浏览器版本都支持了promise
以上方案仅适用于普通业务代码,因为对ES6转化为ES5代码是注入到全局的,如果你是开发组件库的话,这样容易造成类名污染
开发组件库的ES6转化为ES5的方案
https://www.babeljs.cn/docs/babel-plugin-transform-runtime
babel的官网
npm install --save-dev @babel/plugin-transform-runtime
npm install --save @babel/runtime
npm install --save @babel/runtime-corejs2
module:{
rules:[{
test:/\.js$/,
exclude:/node_modules/,
loader:'babel-loader',
options:{
//presets:[['@babel/preset-env',{
// useBuiltIns:'usage',
// targets:{
// edge:"17",
// firefox:"60",
// chrome:"67",
// safari:"11.1"
// }
//}]]
"plugins": [
[
"@babel/plugin-transform-runtime",
{
// "absoluteRuntime": false,
"corejs": 2,
"helpers": true,
"regenerator": true,
"useESModules": false
}
]
]
}
}]
}
//index.js
// import "@babel/polyfill"
const arr = [
new Promise(()=>{}),
new Promise(()=>{})
]
arr.map(item=>{
console.log(item)
})
当我们配置webpack时。会发现嵌套很多层,我们可以在根目录下新建.babelrc
文件,然后将options中的内容复制到.babelrc
中
// .babelrc
{
"plugins": [
[
"@babel/plugin-transform-runtime",
{
// "absoluteRuntime": false,
"corejs": 2,
"helpers": true,
"regenerator": true,
"useESModules": false
}
]
]
}
配置React代码打包
借助babel打包react代码https://www.babeljs.cn/docs/babel-preset-react
mkdir webpack-react
cd webpack-react
npm init -y
npm install webpack webpack-cli -D
安装转化es的依赖
npm install --save-dev babel-loader @babel/core @babel/preset-env
npm install --save @babel/polyfill
module.exports = {
module:{
rules:[
{
test:/\.js$/,
exclude:/node_modules/,
loader:'babel-loader',
options:{
"presets":[["@babel/preset-env",{
targets:{
edge:"17",
firefox:"60",
chrome:"67",
safari:"11.1"
},
useBuiltIns:"usage"
}]]
}
}
]
}
}
安装react依赖
npm install react react-dom --save
编写react代码
import "@babel/polyfill"
import React ,{Component} from 'react';
import ReactDom from 'react-dom'
class App extends Component {
render(){
return <div>hello world</div>
}
}
ReactDom.render(<App></App>,document.getElementById('root'))
此时npm run start
会报错,因为webpack不能直接打包react我们需要借助babel
npm install --save-dev @babel/preset-react
// webpack.config.js
rules:[
{
test:/\.js$/,
exclude:/node_modules/,
loader:'babel-loader',
options:{
"presets":[
["@babel/preset-env",{//再来转化es6
targets:{
edge:"17",
firefox:"60",
chrome:"67",
safari:"11.1"
},
useBuiltIns:"usage"
}],
"@babel/preset-react"//先转化react,
]
}
}
]
注意babel-loader的顺序不能变,必须先转化react, 再去转化ES6
npm run start
此时浏览器就可以正常显示react的内容了
结语
如果文章中有错漏处,请看官们指正 如果觉得文章不错的话,请点个赞吧。 作者:胡志武 时间:2020/01/03