webpack核心,babel的使用

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,可以发现其内容相当多,概念相当多,但其实好多配置是固定的,常用的配置就是几种,大家记住本文这些常用的就行了,感兴趣扩展的可以自己再去扩展。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341