webpack中使用babel處理es6語法


index.js
const arr = [
  new Promise(()=>{}),
  new Promise(()=>{})
];

arr.map(item => {
  console.log(item);
})

 

index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>html template</title>
  </head>
  <body>
    <div id='root'></div>
  </body>
</html>

運行npx webpack(用dev-server打包放在了緩存里面,看不到最終的打包內容)。看到打包生成的main.js的最后幾行,index里面寫的js,原封不動的打包到了main.js里面。這個時候瀏覽器中運行,可以打印出promise對象。好像是沒問題的,這是什么原因呢,這是因為chrome更新比較快,es6里面很多東西,他都做了實現,所以直接在chrome瀏覽器寫es6語法沒問題,但是比如在ie或者更新沒那么快的瀏覽器,,,就會報錯。。。

 

這個時候需要接住babel,https://babeljs.io/。
先安裝兩個包
npm install --save-dev babel-loader @babel/core
一個是幫助webpack打包用的工具,一個是babel的核心庫

webpack配置babel相關

module.exports = {
  module: {
    rules:[{
      test: /\.js$/,
      exclude: /node_modules/,
      loader: "babel-loader"
    }]
  }
}

 

再繼續安裝
npm install @babel/preset-env --save-dev

 

 

為什么要安裝這個模塊,當我們使用babel-loader處理js文件的時候,實際上這個babel-loader只是webpack和babel做通信的一個橋梁,用了他之后,webpack和babel做了打通,但實際上,babel-loader並不會幫助我們把es6語法翻譯成es5語法,還需要借助一些其它的模塊才能夠幫助我們把es6語法翻譯成es5語法。babel/preset-env就是這樣的一個模塊,這里面包含了所有把es6轉化成es5的規則。裝好之后,還需要在webpack里面配置一下
module.exports = {
  module: {
    rules:[{
      test: /\.js$/,
      exclude: /node_modules/,
      loader: "babel-loader",
      options:{
        "presets": ["@babel/preset-env"]
      }
    }]
  }
}
再使用npx webpack,看轉化后的main.js,發現es6的語法轉化成了es5的語法。但是光做到這點不夠。為什么呢?因為比如像Promise這樣新的語法變量,包括數組里面這個map方法,在低版本的瀏覽器里,實際上還是不存在的。雖然了語法翻譯,但只翻譯了一部分。還有一些對象或者函數在一些低版本的瀏覽器里面還是沒有的。

 

所以不僅要用preset-env翻譯es6,還需要將缺失的語法補充到瀏覽器里,這個模塊就是babel/polyfill。然后把polyfill引入到業務代碼的最頂部
index.js
import "@babel/polyfill";

const arr = [
  new Promise(()=>{}),
  new Promise(()=>{})
];

arr.map(item => {
  console.log(item);
});
處理好后,再運行,會發現原來打包好的main是28kb,現在是534kb。這多出來的內容就是polyfill彌補的內容,所以main.js一下子就變的很大。那么我不想要這么大,我只需要你在我需要補充語法的時候出來相應處理的代碼就可以。

安裝

 npm install core-js --save-dev

 

 
module.exports = {
  module: {     rules:[{       test:
/\.js$/,       exclude: /node_modules/,       loader: "babel-loader",       options:{         presets: [['@babel/preset-env',{         /**         * 當我做polyfill填充的時候,去加一些低版本特性的時候,我不是把所有特性都加進來         * 是根據你的業務代碼來決定要加什么         */         useBuiltIns: 'usage',         corejs: 3         }]]       }     }]   } }
主頁打包出來的main就124kb,小了很多

 

當然preset也可以配置一些額外的參數
module.exports = {
  module: {
    rules:[{
      test: /\.js$/,
      exclude: /node_modules/,
      loader: "babel-loader",
      options:{
        presets: [['@babel/preset-env',{
        /**
        * 意思是我的這個項目,打包會運行在>67這個版本的chrome瀏覽器下
        * 比如chrome瀏覽器在67版本以上對es6語法支持很好了,就不需要翻譯
        */
        targets: {
          chrome: "67",
        },
        /**
        * 當我做polyfill填充的時候,去加一些低版本特性的時候,我不是把所有特性都加進來
        * 是根據你的業務代碼來決定要加什么
        * @babel/polyfill,放在js入口
        */
        useBuiltIns: 'usage',
        corejs: 3
        }]]
      }
    }]
  }
}

 

再運行npm run bundle,發現main.js重新變成了28.8kb。

這種方案不一定所有場景都適用,在開發一個第三方模塊的時候,這個時候用polyfill注入是有問題的,因為這是時候注入會以全局變量的方式注入,會污染到全局環境。所以我們在打包UI組件庫或者類庫的時候,需要換一種打包的方式。去除index的pollfile。webpack也不做presets的配置了
首先安裝
npm install --save-dev @babel/plugin-transform-runtime
npm install --save @babel/runtime

 


index.js
// import "@babel/polyfill";

const arr = [
  new Promise(()=>{}),
  new Promise(()=>{})
];

arr.map(item => {
  console.log(item);
})

module.exports = {
  module: {
    rules:[{
      test: /\.js$/,
      exclude: /node_modules/,
      loader: "babel-loader",
      options:{
        "plugins": [["@babel/plugin-transform-runtime",{
        "absoluteRuntime": false,
        "corejs": 2,
        "helpers": true,
        "regenerator": true,
        "useESModules": false
        }]]
      }
    }]
  }
}

 

再強調一遍,如果我們寫的只是業務代碼,在配置的時候只要配置presets,同時引入pollfill就可以了。如果你寫的是一個庫項目代碼的時候,這個時候要使用babel/plugin-transform-runtime。這個時候可以有效的避免presets,或者說是pollfill的問題。pollfile會污染全局環境。但是plugin-transform-runtime會以閉包的方式注入。這樣寫類庫的時候是更好的方式。

另外補充一個知識點,如果我們認真的去配置babel相關的配置,會發現非常的長。我們可以在根目錄新建一個文件。叫.babelrc。然后把options對象拿出來放到.babelrc里面。然后刪除babel配置的option
.babelrc
{
  "plugins": [["@babel/plugin-transform-runtime",{
  "absoluteRuntime": false,
  "corejs": 2,
  "helpers": true,
  "regenerator": true,
  "useESModules": false
  }]]
}

 

webpack.config.js
module.exports = {
  module: {
    rules:[{
      test: /\.js$/,
      exclude: /node_modules/,
      loader: "babel-loader"
    }]
  }
}
這樣執行起來 npm run bundle 不會有任何問題


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM