Webpack 入門指南 - 2.模組

來源:互聯網
上載者:User

標籤:入門指南   []   class   運行   exports   設定檔   系統   style   建立   

這一次我們談談模組問題。

通常我們希望這個項目可以分為多個獨立的模組,比如,上一次提高的 hello 函數,如果我們定義為一個模組,其它模組引用之後,直接調用就好了。在前端怎麼使用模組呢?這可說來話長了。

如果我們把 hello 函數定義在檔案 hello.js 中,內容如下:

function hello(){    alert("Hello, Webpack!");}

然後把主入口函數 index.js 的內容寫成下面的內容,你應該會得到一個錯誤資訊。

require("./hello");hello();

對話方塊是彈不出來的。錯誤資訊如下:

Uncaught ReferenceError: hello is not defined, 明明定義了 hello 函數,卻偏偏說找不到。

1. CommonJs 模組

CommonJs 是目前比較流行,也是出現較早的模組技術,它誕生於 NodeJs,使用起來其實比較簡單。

首先,它把一個獨立的檔案看成一個模組,比如上面的 hello.js 檔案,就可以當成一個模組。模組的名稱就是檔案名稱,但是可以不用提供副檔名 .js,直接使用檔案名稱就可以。

在匯入一個模組的時候,使用 require 函數,注意是函數,並不是關鍵字,JavaScript 並沒有提供這個關鍵字。函數的參數就是模組名稱,不過,要注意模組分為兩種,自訂的模組和系統模組。

自訂的模組必須使用 . 或者 .. 開頭的相對路徑,如果都在同一個目錄下,也需要使用 . 來表示當前路徑,比如上面用到的 require("./hello")。

不是使用 . 或者 .. 開始的相對路徑的,都稱為系統模組,系統模組的路徑其實在 node_modules 檔案夾中,每個子檔案夾就是一個系統模組。

require 函數的返回結果就是模組匯出的內容。

我們的模組沒有匯出任何內容。所以,雖然被 index 引用了,但是在 index 中卻是無法訪問的。這也說明模組中定義的函數其實是局部函數,並不是通常意義上的全域函數了。

我們要在模組中匯出內容怎麼辦呢,CommonJs 提供了 exports 對象。

在 CommonJs 模組中,希望匯出的內容必須通過 exports 對象,這是 CommonJs 系統提供的系統對象,我們可以直接使用。匯出的內容以索引值對的形式定義到這個對象上,鍵就是匯出的名稱,值就是準備匯出的內容。

比如,我們希望將 hello 函數匯出為名為函數的函數,好像挺繞的,其實很簡單。

function hello(){    alert("Hello, Webpack!");}exports.hello = hello;

將 index.js 函數的定義修改為

var hello = require("./hello").hello;hello();

重新執行 webpack 命令,重新整理網頁,你會看到函數執行了。

 

2. AMD 模組

另外一個著名的模組系統稱為 AMD 模組,全稱為 Asynchromous Module Defination,翻譯過來就是非同步模組規範,它是由 RequireJs 推動的。

首先,一個檔案也被看作一個模組,所以,我們還拿 hello.js 作為一個模組吧。

其次,定義模組使用 define 函數,函數的第一個參數是當前模組依賴的模組數組,如果沒有依賴的函數,可以使用一個空的數組表示。

define([], function(){    return {        hello: function(){            alert("Hello, Webpack!");        }    };});

 

第二個參數就是模組的定義函數,這個函數的返回內容就是模組的匯出內容。我們這裡匯出一個對象包含我們定義的函數的對象。

最後,我們修改一下 index.js 來匯入定義好的 AMD 模組,並調用 hello 函數。

define([‘./hello‘], function( helloModule ){    helloModule.hello();})

 

這次,我們的 index 依賴提前定義好的 hello 模組,注意模組命名的方式還是注意自訂模組和系統模組的區別,在第二個函數參數中,它的參數就是被相依模組匯出的內容,所以這裡的 helloModule 就是一個對象,它的 hello 屬性就是我們定義好的函數。

3. ES 2015 和 TypeScript 中的模組

在 ES2015 中,定義了關鍵字,注意是關鍵字,不是函數了,模組匯出的關鍵字是 export , 匯入就是 import 了。

所以,hello 函數可以這樣定義了。

export default function() {    alert("Hello, Webpack!");};    

 

而 index.js 就可以這樣定義。

import hello from "./hello";hello();

 

但是,需要注意的是,你必須有 ES2015 的運行環境才行,目前很多瀏覽器不支援怎麼辦呢?

我們可以將 ES2015 的代碼先翻譯成標準的 JavaScript 代碼,就可以執行了。

而 TypeScript 作為 ES2015 的超集,我們就使用 TypeScript 來實現。

首先,你必須確認你已經安裝了 TypeScript 的編譯器,全域安裝 TypeScript

npm -g install typescript

 

安裝之後,可以執行 tsc -v 來檢查版本,目前最新是 2.0.3 版本。

將 hello.js 重新改名為 hello.ts,將 index.js 改名為 index.ts. ts 是 TypeScript 檔案的副檔名。

你可以手工執行命令 tsc 分別將兩個 typescript 檔案編譯為 javascript 檔案。

產生的 hello.js

"use strict";function default_1() {    alert("Hello, Webpack!");}exports.__esModule = true;exports["default"] = default_1;;

 

產生的 index.js

"use strict";var hello_1 = require("./hello");hello_1["default"]();

 

 

然後,再次執行 webpack 重新打包,你會發現結果仍然正常執行。

4. 使用 tsloader 

在第三步,我們可以手工使用 tsc 將 TypeScript 代碼編譯為 JavaScript 代碼之後進行打包,但是這樣太麻煩了,使用 ts-loader 我們可以讓 webpack 自動先調用 tsc 將 TypeScript 代碼編譯為 JavaScript 代碼,然後再自動進行打包工作。

首先,當然要安裝 ts-loader 外掛程式了。

npm install ts-loader --save-dev

 

目前是 0.9.5 版本。

為了在項目中使用 typescript,你還需要本地安裝 typescript 一次。

npm install typescript --save-dev

 

還需要配置一下 TypeScript 如何編譯代碼。在目前的目錄中建立名為 tsconfig.json 的設定檔。

{  "compilerOptions": {    "target": "es5",    "sourceMap": true  },  "exclude": [    "node_modules"  ]}

 

這裡的配置是說,希望產生 es5 標準的 JavaScript 目標檔案。

然後,配置 webpack 使用 ts-loader

var HtmlwebpackPlugin = require(‘html-webpack-plugin‘);module.exports = {    // 入口    entry: "./index.ts",    // 輸出的檔案名稱    output: {        filename: ‘bundle.js‘    },    resolve: {        // Add `.ts` and `.tsx` as a resolvable extension.        extensions: [‘‘, ‘.ts‘, ‘.js‘]    },    // 添加我們的外掛程式 會自動產生一個html檔案    plugins: [        new HtmlwebpackPlugin({            title: ‘Hello Webpack‘        })    ],    module: {        loaders: [            // all files with a `.ts` extension will be handled by `ts-loader`            { test: /\.ts$/, loader: ‘ts-loader‘ }        ]    }};

 

這裡增加了兩個內容,一個是 resolve 配置,這樣我們只需要使用模組名稱,webpack 會自動添加尾碼來尋找模組檔案。另一個就是 module 中的 loader 了,這裡是說遇到了 .ts 副檔名的檔案,需要先使用 ts-loader 處理之後再打包。

現在,重新執行 webpack 命令,你會發現一切都已經處理好了,重新整理頁面,你應該看到代碼正確執行了。

5. 總結

webpack 可以直接支援 CommonJs 和 AMD 模組,對於 TypeScript ,我們還需要安裝 TypeScript 和 ts-loader.

需要注意的是 Angular 2 使用 TypeScript 作為主力語言,你能做到這裡,離 Angular 2 已經很近了。

 

Webpack 入門指南 - 2.模組

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.