npm 6.14 + Babel 7 使用


Babel官網

Babel github :https://github.com/babel/babel/tree/master/packages

Babel 在線轉化:https://www.babeljs.cn/repl

Babel 是干嘛的

用於將 ECMAScript 2015+ 版本的代碼轉換為向后兼容的 JavaScript 語法,以便能夠運行在當前和舊版本的瀏覽器或其他環境中。下面列出的是 Babel 能為你做的事情:

  • 語法轉換
  • 通過 Polyfill 方式在目標環境中添加缺失的特性 (通過 @babel/polyfill 模塊)
  • 源碼轉換 (codemods)

npx

在Babel使用之前先介紹一下npx,因為后面用到npx,注意不是npm

npx是啥

npx是一種在npm中安裝工具,也可以被單獨的下載使用

在npm 5.2.0 的時候發現會買一送一,自動安裝了npx。

也就是說 npm5.2之后,會自動安裝

npx是解決什么問題的

再也不需全局安裝任何工具只需要npx <commang>

為什么使用npx

全局安裝劣勢:

  • 占用本機空間

    npm會在machine上創建一個目錄(mac是/usr/local/lib/node_modules)存放所有global安裝的包, 其實node_module占用的空間比較大的

  • 版本問題:

    假如一個項目中的某一個dependency是全局安裝的,也就意味着不同的開發人員使用的這個dependency版本完全基於本地的版本,也就會導致不同的開發人員使用不同的版本

使用npx的優勢也就凸顯出來了:

  • 當在執行

    npx <command>
    

    的時候,npx會做什么事情?

    • 幫你在本地(可以是項目中的也可以是本機的)尋找這個 command
      • 找到了: 就用本地的版本
      • 沒找到: 直接下載最新版本,完成命令要求
    • 使用完之后不會在你的本機或者項目留下任何東西

因此優勢總結:

  • 不會污染本機
  • 永遠使用最新版本的dependency

Babel使用

配置Node項目環境

執行

npm init -y

然后項目目錄下就會創建一個package.json,如

image-20201013144435261

下載相應的包的命令

npm install --save-dev @babel/core @babel/cli @babel/preset-env
npm install --save @babel/polyfill
 
或者簡寫:
 
npm install -D @babel/core @babel/cli @babel/preset-env
npm install @babel/polyfill

(--save-dev(簡寫-D)表示該版本只適用於開發環境中,命令會自動幫你寫在package.json的devDependencies中

--save(或者不寫)則表示該版本適用於生產環境中,命令會自動幫你寫在package.json的dependencies中 )

如:

image-20201013144838047

使用Babel前要下載的包的意義和用法

@babel/core

Babel 的核心功能在 @babel/core模塊,如果某些代碼需要調用Babel的API進行轉碼,則就需要此模塊。

用法如下

var babel = require('@babel/core');
// 字符串轉碼
babel.transform('code();', options);
// => { code, map, ast }

// 文件轉碼(異步)
babel.transformFile('filename.js', options, function(err, result) {
  result; // => { code, map, ast }
});

// 文件轉碼(同步)
babel.transformFileSync('filename.js', options);
// => { code, map, ast }

// Babel AST轉碼
babel.transformFromAst(ast, code, options);
// => { code, map, ast }

@babel/polyfill

模塊包括core-js和自定義regenerator runtime 來模擬完整的 ES2015+ 環境。

Babel默認只轉換新的JavaScript句法(syntax),而不轉換新的API,比如Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise等全局對象,以及一些定義在全局對象上的方法(比如Object.assign)都不會轉碼。

舉例來說,ES6在Array對象上新增了Array.from方法。Babel就不會轉碼這個方法。如果想讓這個方法運行,必須使用babel-polyfill,為當前環境提供一個墊片

@babel/preset-env

根據你需要支持的環境(配合targets中的瀏覽器信息)自動決定適合你的 Babel 插件

@babel/cli

@babel/cli是一個允許你從終端使用 babel 的工具。即用於命令行轉碼

全局安裝命令

npm install -D @babel/cli -g

基本用法如下。

# 轉碼結果輸出到標准輸出(字符串形式輸出)
$ babel example.js

# 轉碼結果寫入一個文件
# --out-file 或 -o 參數指定輸出文件
$ babel example.js --out-file compiled.js

# 或者
$ babel example.js -o compiled.js

# 整個目錄轉碼
# --out-dir 或 -d 參數指定輸出目錄
$ babel src --out-dir lib
# 或者
$ babel src -d lib

# -s 參數生成source map文件
$ babel src -d lib -s

創建配置文件

使用以下內容在項目的根目錄中創建名為 babel.config.js 的配置文件:(配置文件很重要)

module.exports = function(api){
    api.cache(true)
    const presets = [
        ["@babel/env", {
          targets: {
            ie:"10",
            edge: "17",
            firefox: "60",
            chrome: "67",
            safari: "11.1"
          },
          useBuiltIns: "usage"
        }]
      ];
      const plugins = [];
      return {
        presets,
        plugins
      }
}

//target表示你想要支持的瀏覽器的最低型號
// useBuiltIns: "usage" ——由於polyfill包很臃腫,Babel 的此設置將檢查你的所有代碼,以查找目標環境中缺少的功能,並僅包含所需的 polyfill。

開始使用

創建src文件夾,再在里面創建index.js文件,並輸入

(x => x * 2)(1)

在命令行中輸入

//表示src整個目錄轉碼到dist目錄下
npx babel src -d dist

結果如下

image-20201013153430511

可以看到已經被成功編譯

es6相關特性編譯問題

class 不支持

上面安裝了@babel/polyfill包 編譯Promise等全局對對象沒問題,但是你會發現class類 這個特性編譯不了

image-20201013154717181

這是因為還缺少一個插件@babel/plugin-proposal-class-properties

安裝

npm install @babel/plugin-proposal-class-properties -D

在配置文件中加入插件配置

const plugins = [
        '@babel/plugin-proposal-class-properties'
    ];

此時的babel.config.js

module.exports = function(api){
    api.cache(true)
    const presets = [
        ["@babel/env", {
            targets: {
                ie:"10",
                edge: "17",
                firefox: "60",
                chrome: "67",
                safari: "11.1"
            },
            useBuiltIns: "usage"
        }]
    ];
    const plugins = [
        '@babel/plugin-proposal-class-properties'
    ];
    return {
        presets,
        plugins
    }
}

執行編譯

npx babel src -d dist

編譯結果

image-20201013155825940

class 編譯之后出現 require()

如果你的類比較復雜,如

class A {
    constructor() {
        console.log('A構造方法');
    }
}
class B extends A{
    constructor() {
        super();
        console.log('B構造方法')
    }
}

你運行編譯命令之后,你會發現,編譯完成的文件是這樣的

npx babel src -d dist

image-20201013164531970

你會發現居然出現了require(),這不是node的嗎,為什么編譯之后會出現這個?並且你會發現直接注釋掉也可以引入運行,如

image-20201014165708058

image-20201014165727184

找不到require()里面的相關文件

你順着它引入的文件去模塊里面去找,你會發現這些文件你都找不到,這是為什么,怎么解決?

image-20201014114103630

這時候你再用Babel編譯一次,你會發現

npx babel src -d dist

編譯有個警告

image-20201014114233820

大概意思就是沒有指定corejs的版本,就是這個的原因

首先安裝corejs

npm install --save core-js@3

然后在配置文件babel.config.js中加入corejs : 3的設置選項

這時候配置文件是這樣的

module.exports = function(api){
    api.cache(true)
    const presets = [
        ["@babel/env", {
            targets: {
                ie:"10",
                edge: "17",
                firefox: "60",
                chrome: "60",
                safari: "11.1"
            },
            useBuiltIns: "usage",
            corejs : 3
        }]
    ];
    const plugins = [
        '@babel/plugin-proposal-class-properties',
    ];
    return {
        presets,
        plugins
    }
}

再次執行Babel編譯命令

npx babel src -d dist

沒有警告了

image-20201014114736338

再次打開,發現可以找到相關文件了

image-20201014114918730

但是require()還是有,瀏覽器不可能支持require()。babel 是怎么編譯es6的模塊的,怎么會出現require()?

其實就一句話:

babel 統一將 js 模塊化語法轉為 commonJS 風格。

從Babel 6.0開始,不再直接提供瀏覽器版本,需要配合webpack等構建工具使用。如果你的項目相當簡單,並不需要使用構建工具,而你又想在Web項目中使用ES6的語法,Babel+Browserify可以滿足你的需求。

安裝Browserify

官網:http://browserify.org/

github:https://github.com/browserify/browserify

npm install browserify -D

執行Browserify編譯

npx browserify ./dist/testClass.js -o test.js

結果如下image-20201014142650790

編譯是編譯完了,還是有require(),但是好像自己實現了,那html頁面引入怎么用呢?

看了下生成的結構

image-20201014181235622

這是自調用的閉包,頁面直接引入不可能可以調用的,那怎么在html直接引入調用呢?出現這種情況是為什么呢?這是因為

默認情況下,Browserify不允許從瀏覽器序列化代碼之外訪問模塊。如果要調用瀏覽器序列化模塊中的代碼,則應該將代碼與模塊一起瀏覽

參考:https://cloud.tencent.com/developer/ask/109752

npx browserify ./dist/testClass.js --standalone Main -o testClass.js

設置導出到全局的模塊

來到我們使用Babel編譯后的文件

加入模塊導出語句

例:

module.exports = B;

image-20201016160245279

執行編譯
其實就是將我們導出的模塊掛載到window對象下,使我們頁面能夠直接訪問

#npx browserify [Babel編譯后的文件路徑] --standalone 導出的模塊名 -o 導出的文件位置
npx browserify ./dist/testClass.js --standalone B -o testClass.js

頁面引入執行

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--<script src="./dist/testClass.js"></script>-->
    <script src="testClass.js"></script>
</head>
<body>

<script>
    console.log(B);
</script>
</body>
</html>

運行結果

image-20201016160740224


免責聲明!

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



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