1. ES6的编译
      ES6的编译需要安装的loader: npm install babel-loader @babel/core —save-dev

    文件目录中app.js中,写一个箭头函数。

    在config文件中配置loader如下,进行webpack打包,但是发现并没有编译(因为箭头函数依然存在),是因为webpack不知道要编译成满足什么规范的JS,所以也就是我们需要告诉webpack我们需要打包生成的js是什么规范 。
    比如是:ES2015,

    ES2016,
    ES2017,
    env, (通常采用这个规范)
    babel-preset-stage

    babel-preset:是存储JS不同标准的插件(babel的插件),通过正确使用presets,告诉babel按照哪个规范进行编译。
    安装babel-preset: npm install @babel/preset-env —save-dev

    1. module.exports = {
    2. entry: {
    3. app: './app.js'
    4. },
    5. output: {
    6. filename: '[name].[hash:8].js'
    7. },
    8. module: {
    9. rules: [
    10. {
    11. test: /\.js$/,
    12. use: 'babel-loader'
    13. }
    14. ]
    15. }
    16. }

    修改webpack的config文件,配置babel-loader的presets:
    presets使用 @babel/preset-env,编译 targets为市场占有率大于1%的浏览器。

    1. module.exports = {
    2. entry: {
    3. app: './app.js'
    4. },
    5. output: {
    6. filename: '[name].[hash:8].js'
    7. },
    8. module: {
    9. rules: [
    10. {
    11. test: /\.js$/,
    12. use: {
    13. loader: 'babel-loader',
    14. options: {
    15. presets: [
    16. ['@babel/preset-env',{
    17. targets:{
    18. browsers: ['>1%']
    19. }
    20. }]
    21. ]
    22. }
    23. }
    24. }
    25. ]
    26. }
    27. }

    基于以上配置,再次webpack打包,会发现箭头函数别编译成了普通函数。

    Babel-preset的target配置:
    Target是preset的核心配置,告诉preset编译的具体目标。Target可以是:
    (1)以browser为目标;(通常情况)
    (2)以node的版本为目标;
    (3)以特定的浏览器为目标;

    以node为目标和以特定浏览器为目标:例子中的node和chrome版本均已支持ES6,所以箭头函数不会被编译。

    1. module: {
    2. rules: [
    3. {
    4. test: /\.js$/,
    5. use: {
    6. loader: 'babel-loader',
    7. options: {
    8. presets: [
    9. ['@babel/preset-env',{
    10. targets:{
    11. // browsers: ['>1%']
    12. // node: "10"
    13. // chrome: "59"
    14. }
    15. }]
    16. ]
    17. }
    18. }
    19. }
    20. ]
    21. }

    babel-loader是只能编译ES6的语法,但是对于ES6的方法的无能为力的,比如ES6中有sort排序方法。这时候就需要另外两个模块的帮助:
    babel-polyfill
    babel-plugin-transform-runtime(需要同时安装 babel-runtime)

    安装这两个库:
    npm install babel-polyfill —save-dev
    npm install babel-plugin-transform-runtime babel-runtime —save

    babel-polyfill的生效方式:
    在打包文件生成一个全局对象,将ES6的方法用ES5规范全部实现一遍,在运行的时候,实际上调用的babel-polyfill生成的ES5的方法。一般用于项目开发。

    使用babel-polyfill,并不需要我们在配置文件中编写,只需要在js中 import 它就可以了。

    1. import 'babel-polyfill';
    2. setTimeout(() => {
    3. console.log(1);
    4. }, 200);

    在使用babel-polyfill之前,可以注意一下打包出来的js文件大小:
    image.png
    使用babel-polyfill之后:
    image.png
    发现打包文件体积明显增大很多,是因为babel-polyfill 生成的全局对象里包含的方法,它包含了所有ES6的新方法的实现,所以体积变大很多。

    app.js中,使用了Promise,可以在打包文件中发现Promise的实现,其实也就是使用的是babel-polyfill生成的方法。

    1. import 'babel-polyfill';
    2. new Promise(setTimeout(() => {
    3. console.log(1);
    4. }, 200));

    也可以在config文件中引入babel-polyfill,使其生效,如下:

    1. entry: {
    2. app: ['babel-polyfill','./app.js']
    3. },

    babel-transform-runtime的生效方式:
    它会生成一个局部对象,比如在上面的实例app.js中,这个局部对象只会在app.js中,并且只会包含使用了的ES6方法,并不会包含没有使用的ES6方法,如上面的Promise,则只会包含Promise的实现。它并不会特别明显的增加打包文件的体积,一般用于框架的开发。

    在webpack4中,安装babel-transform-runtime:
    npm install @babel/plugin-transform-runtime @babel/runtime
    app.js如下:

    1. new Promise(setTimeout(() => {
    2. console.log(1);
    3. }, 200));
    4. async function a() {
    5. console.log("Hello!");
    6. }

    config如下:配置在plugins下,需要将刚才的polyfill去掉。

    1. module: {
    2. rules: [
    3. {
    4. test: /\.js$/,
    5. use: {
    6. loader: 'babel-loader',
    7. options: {
    8. presets: [
    9. ['@babel/preset-env',{
    10. targets:{
    11. browsers: ['>1%']
    12. }
    13. }]
    14. ],
    15. plugins:[
    16. ["@babel/transform-runtime"]
    17. ]
    18. }
    19. }
    20. }
    21. ]
    22. }

    打包后的文件大小并不是很大:
    image.png

    如果babelloader的options配置过于庞大的话,影响阅读,可以将这部分单独提取出来,在当前目录新建 .babelrc 文件,将options的配置移入到该文件中,wepack会自动去这个文件中去读取相关配置。

    1. {
    2. "presets": [
    3. ["@babel/preset-env",{
    4. "targets":{
    5. "browsers": [">1%"]
    6. }
    7. }]
    8. ],
    9. "plugins":[
    10. ["@babel/transform-runtime"]
    11. ]
    12. }
    1. 语法糖的编译
      以typescript为例:
      安装:
      npm install typescript ts-loader —save-dev
    1. const hello: string = "Hello world!";
    2. console.log(hello);
    1. import "./test.ts";
    2. new Promise(setTimeout(() => {
    3. console.log(1);
    4. }, 200));
    5. async function a() {
    6. console.log("Hello!");
    7. }


    webpack.config.js文件:

    1. module.exports = {
    2. entry: {
    3. app: ['./app.js']
    4. },
    5. output: {
    6. filename: '[name].[hash:8].js'
    7. },
    8. module: {
    9. rules: [
    10. {
    11. test: /\.js$/,
    12. use: {
    13. loader: 'babel-loader'
    14. }
    15. },
    16. {
    17. test: /\.tsx?$/,
    18. use: "ts-loader"
    19. }
    20. ]
    21. }
    22. }

    另外还需要配置ts-loader具体的参数,增加tsConfig.json,如下所示:

    1. {
    2. "compilerOptions":{
    3. "module":"commonjs",
    4. "target":"es5"
    5. },
    6. "exclude":["./node_modules"]
    7. }