美文网首页
webpack核心,babel的使用

webpack核心,babel的使用

作者: 喜剧之王爱创作 | 来源:发表于2020-08-13 22:33 被阅读0次
babel.png

什么是Babel?

在进行讲解之前, 我们先把我们之前的项目精简一下,只留一个index.js,内容如下,

const arr = [
    new Promise(() => {}),
    new Promise(() => {}),
]
arr.map(item => {
    console.log(item)
})

我们在上面使用的ES6的语法,现在对项目进行打包,这里我们不用devServer,因为我们想听过打包,去分析一下/dist/main.js,这里关于打包的知识就不讲了。我们看main.js中的最后几行代码,可以看到如下的代码

/*! no static exports found */
/***/ (function(module, exports) {

eval("const arr = [\r\n    new Promise(() => {}),\r\n    new Promise(() => {}),\r\n]\r\narr.map(item => {\r\n    console.log(item)\r\n})//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvaW5kZXguanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvaW5kZXguanM/YjYzNSJdLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBhcnIgPSBbXHJcbiAgICBuZXcgUHJvbWlzZSgoKSA9PiB7fSksXHJcbiAgICBuZXcgUHJvbWlzZSgoKSA9PiB7fSksXHJcbl1cclxuYXJyLm1hcChpdGVtID0+IHtcclxuICAgIGNvbnNvbGUubG9nKGl0ZW0pXHJcbn0pIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./src/index.js\n");
/***/ })

可以看到,里面有箭头函数,有const,有Promise这些ES6的代码,可以说原封不动的做了打包,实际上这样做事可能存在一些问题的,比如我们在低版本的浏览器中,比如我们在不支持Promise的浏览器中(IE:别瞅我~),这些代码都会失效,于是我们期望有没有一种技术可以让我们在打包的时候,将这种ES6的语法转成ES5,这样他就能再各种浏览器下运行了,这种技术就是babel
我们可以进入到babel官网,可以看到哈,如官网所说,Babel 是一个 JavaScript 编译器。我先来从头教大家如何去使用一个babel

  • 我们到"设置"中,先来选择一个babel的使用场景,这里我们选择webpack
  • 按照指南,我们看到了,设立需要我们去安装bable-loader@babel/core,大家看到loader肯定是陌生,这里肯定是为了满足Webapck模块打包的,@babel/core实际上就是babel的核心库了。
  • 在配置中加一条规则
module: {
  rules: [
    { test: /\.js$/, exclude: /node_modules/, loader: "babel-loader" }
  ]
}

意思是如果我们遇到js代码,我们就只用babel-loader进行分析。其中exclude的意思是如果你的js文件是在node_modules里面,我们就不使用babel-loader了。因为node_modules里面的代码都是第三方的代码,我们没必要对第三方的代码进行ES6转ES5的操作。并且这些第三方的模块一般早就给我们做了这一步,我们也没必要重复去做。

  • 安装@babel/preset-env,实际上,babel-loader相当于webpack和babel之间的桥梁,只是帮我们把功能打通,要想进行转移,我们还需要借助@babel/preset-env来帮我们做真正的编译功能,他里面包含了一些翻译规则等...
npm install @babel/preset-env --save-dev
  • 修改配置
{ 
  test: /\.js$/,
  exclude: /node_modules/,
  loader: "babel-loader",
    options: {
      presets: ["@babel/preset-env"]
    }
}

接下来,让我们打包试一下看看是不是ES6语法标称了ES5,当然,结果肯定是~ :)
但是我们会发现,这里的Promise其实还是不被IE浏览器支持的,这里我们会使用@babel/polyfill来兼容低版本浏览器。

使用@babel/polyfill兼容低版本浏览器

我们到babel官网的文档中,找到@babel/polyfill,然后做出相应的配置。

  • 安装
npm install --save @babel/polyfill
  • 使用
    @babel/polyfill应用到业务代码最顶端
import "@babel/polyfill";
const arr = [
    new Promise(() => {}),
    new Promise(() => {}),
]
arr.map(item => {
    console.log(item)
})

这时候我们打包试一下,我们会发现一个问题,main.js体积暴增。我这边已经达到了900多kb,这多的内容就是@babel/polyfill在弥补低版本浏览器一些内容,自己做了一些实现。然后把他们注入进main.js。包括一些我们并没有在项目中用到的一些语法,只注入我们用到的就可以了,那么我们该如何去优化这一点呢?
我们需要对babel-loader的配置改成下面这样

{
    test: /\.js$/,
    exclude: /node_modules/,
    loader: 'babel-loader',
    options: {
        presets: [['@babel/preset-env', {
            useBuiltIns: 'usage'
        }]]
    }
}

这时候,再打包,你会发现,main.js小了不少呢,并且也可以在低版本浏览器下运行了。
当然了,关于babel-loader的presets我们还可以写一些其他内容,这里我们找到一个官网的配置,写进去,

options: {
    presets: [['@babel/preset-env', {
        targets: {
            "edge": "17",
            "firefox": "60",
            "chrome": "67",
            "safari": "11.1",
        },
        useBuiltIns: 'usage'
    }]]
}

上面新加入的配置的意思是,项目运行的浏览器版本环境,用来决定对于JS转译的需求,比如下面的配置

targets: {
  "chrome": "67",
},

意思是@babel/preset-env会根据你规定的浏览器版本去转译,如果67版本对于ES6的兼容很好了,没必要去转了,他就不去注入那些方法了。再重新打包你会发现,main.js又回到了几十kb,在main.js中也没有去转译ES5。

对于babel,其内容有太多太多,甚至比webpack的层次还深,这里不做太多的介绍了,有需求可以去官网看相关配置或者百度~~

你可能不需要@babel/polyfill

这里我们讲了一整篇的babel,其实对于babel有时候并不能按照我们本文讲的情况来配置,比如我们在封装一个组件库的时候,假如像我们上面那样的引入,会造成全局变量的污染,下面我们介绍另外一种方式。(照着官网说明配置即可,这是补充内容,不讲太详细)

@babel/plugin-transform-runtime
  • 安装
npm install --save-dev @babel/plugin-transform-runtime
npm install --save @babel/runtime
npm install --save @babel/runtime-corejs2
  • 配置
    首先注释掉之前index.js中对于@babel/polyfill的引入,然后替换之前的配置如下
options: {
    // presets: [['@babel/preset-env', {
    //     targets: {
    //         "chrome": "67",
    //     },
    //     useBuiltIns: 'usage'
    // }]]
    "plugins": [["@babel/plugin-transform-runtime", {
        "corejs": 2,
        "helpers": true,
        "regenerator": true,
        "useESModules": false,
    }]]
}

这时候打包试试,也是可以正常打包的,这里我们这么做可以避免@babel/polyfill对于全局变量的污染,当然,如果我们是写业务代码,那就使用@babel/polyfill就可以满足了。这种方式用来开发组件库使用是个很好的解决方案。

你可能需要创建一个.babelrc的文件

我们发现,babel的配置项的内容非常的多,要是做比较详细的配置的话,其配置内容也是相当的多,这里我们可以用一个.babelrc的文件来将这些配置分离出来,我们在项目的根目录下新建这个文件。然后将options的内容拿出去就可以了。

写在最后

本篇的内容我们讲解了babel,可以发现其内容相当多,概念相当多,但其实好多配置是固定的,常用的配置就是几种,大家记住本文这些常用的就行了,感兴趣扩展的可以自己再去扩展。

相关文章

网友评论

      本文标题:webpack核心,babel的使用

      本文链接:https://www.haomeiwen.com/subject/wmaidktx.html