tyepscript+webpack搭建

官方學習文檔:https://www.webpackjs.com/guides/getting-started/

首先安裝nodejs (一搜一堆)

npm install npm -g  //更新npm

簡介webpack:webpack 是一個現代 JavaScript 應用程序的靜態模塊打包器(module bundler)。(詳細瞭解

最新的webpack版本是:v4.39.3

 

要安裝最新版本或特定版本,請運行以下命令之一:

npm install --save-dev webpack
npm install --save-dev webpack@<version>

如果你使用 webpack 4+ 版本,你還需要安裝 CLI。

npm install --save-dev webpack-cli

webpack 在全局環境下可用:

npm install --global webpack

 

可在安裝完成提示的路徑下查看:

 

用webpack 用於編譯 JavaScript 模塊:

進入要安裝編譯的目錄下:

首先我們創建一個目錄,初始化 npm,然後 在本地安裝 webpack,接着安裝 webpack-cli(此工具用於在命令行中運行 webpack):

mkdir webpack-demo && cd webpack-demo
npm init -y
npm install webpack webpack-cli --save-dev

創建好打開創建目錄文件夾:

黃色是手動添加,粉色手動修改其內容:

package.json

  {
    "name": "webpack-demo",
    "version": "1.0.0",
    "description": "XXXX項目前端",
+   "private": true,
-   "main": "index.js",
    "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1"
    },
    "keywords": [],
    "author": "Author",
    "license": "ISC",
    "devDependencies": {
      "webpack": "^4.0.1",
      "webpack-cli": "^2.0.9"
    },
    "dependencies": {}
  }

結構:

src/index.js

function component() {
  var element = document.createElement('div');

  // Lodash(目前通過一個 script 腳本引入)對於執行這一行是必需的
  element.innerHTML = _.join(['Hello', 'webpack'], ' ');

  return element;
}

document.body.appendChild(component());

index.html

<!doctype html>
<html>
  <head>
    <title>起步</title>
    <script src="https://unpkg.com/[email protected]"></script>
  </head>
  <body>
    <script src="./src/index.js"></script>
  </body>
</html>

 

要在 index.js 中打包 lodash 依賴,我們需要在本地安裝 library:

npm install --save lodash

在安裝一個要打包到生產環境的安裝包時,你應該使用 npm install --save

如果你在安裝一個用於開發環境的安裝包(例如,linter, 測試庫等),你應該使用 npm install --save-dev

請在 npm 文檔 中查找更多信息。

src/index.js

+ import _ from 'lodash';
+
  function component() {
    var element = document.createElement('div');

-   // Lodash, currently included via a script, is required for this line to work
+   // Lodash, now imported by this script
    element.innerHTML = _.join(['Hello', 'webpack'], ' ');

    return element;
  }

  document.body.appendChild(component());

dist/index.html

  <!doctype html>
  <html>
   <head>
     <title>起步</title>
-    <script src="https://unpkg.com/[email protected]"></script>
   </head>
   <body>
-    <script src="./src/index.js"></script>
+    <script src="main.js"></script>
   </body>
  </html>

在這個設置中,index.js 顯式要求引入的 lodash 必須存在,然後將它綁定爲 _(沒有全局作用域污染)。通過聲明模塊所需的依賴,webpack 能夠利用這些信息去構建依賴圖,然後使用圖生成一個優化過的,會以正確順序執行的 bundle。

可以這樣說,執行 npx webpack,會將我們的腳本作爲入口起點,然後 輸出 爲 main.js。Node 8.2+ 版本提供的 npx 命令,可以運行在初始安裝的 webpack 包(package)的 webpack 二進制文件(./node_modules/.bin/webpack):

npx webpack

Hash: dabab1bac2b940c1462b
Version: webpack 4.0.1
Time: 3003ms
Built at: 2018-2-26 22:42:11
    Asset      Size  Chunks             Chunk Names
main.js  69.6 KiB       0  [emitted]  main
Entrypoint main = main.js
   [1] (webpack)/buildin/module.js 519 bytes {0} [built]
   [2] (webpack)/buildin/global.js 509 bytes {0} [built]
   [3] ./src/index.js 256 bytes {0} [built]
    + 1 hidden module

WARNING in configuration(配置警告)
The 'mode' option has not been set. Set 'mode' option to 'development' or 'production' to enable defaults for this 

project

  webpack-demo
  |- package.json
+ |- webpack.config.js
  |- /dist
    |- index.html
  |- /src
    |- index.js

webpack.config.js

const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  }
};

現在,讓我們通過新配置文件再次執行構建:

npx webpack --config webpack.config.js

Hash: dabab1bac2b940c1462b
Version: webpack 4.0.1
Time: 328ms
Built at: 2018-2-26 22:47:43
    Asset      Size  Chunks             Chunk Names
bundle.js  69.6 KiB       0  [emitted]  main
Entrypoint main = bundle.js
   [1] (webpack)/buildin/module.js 519 bytes {0} [built]
   [2] (webpack)/buildin/global.js 509 bytes {0} [built]
   [3] ./src/index.js 256 bytes {0} [built]
    + 1 hidden module

WARNING in configuration(配置警告)
The 'mode' option has not been set. Set 'mode' option to 'development' or 'production' to enable defaults for this

在 package.json 添加一個 npm 腳本(npm script)

package.json

  {
    "name": "webpack-demo",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1",
+     "build": "webpack"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "devDependencies": {
      "webpack": "^4.0.1",
      "webpack-cli": "^2.0.9",
      "lodash": "^4.17.5"
    }
  }

現在,可以使用 npm run build 命令,來替代我們之前使用的 npx 命令。注意,使用 npm 的 scripts,我們可以像使用 npx 那樣通過模塊名引用本地安裝的 npm 包。這是大多數基於 npm 的項目遵循的標準,因爲它允許所有貢獻者使用同一組通用腳本(如果必要,每個 flag 都帶有 --config 標誌)。

現在運行以下命令,然後看看你的腳本別名是否正常運行:

npm run build

Hash: dabab1bac2b940c1462b
Version: webpack 4.0.1
Time: 323ms
Built at: 2018-2-26 22:50:25
    Asset      Size  Chunks             Chunk Names
bundle.js  69.6 KiB       0  [emitted]  main
Entrypoint main = bundle.js
   [1] (webpack)/buildin/module.js 519 bytes {0} [built]
   [2] (webpack)/buildin/global.js 509 bytes {0} [built]
   [3] ./src/index.js 256 bytes {0} [built]
    + 1 hidden module

WARNING in configuration(配置警告)
The 'mode' option has not been set. Set 'mode' option to 'development' or 'production' to enable defaults for this environment.('mode' 選項還未設置。將 'mode' 選項設置爲 'development' 或 'production',來啓用環境默認值。)

通過向 npm run build 命令和你的參數之間添加兩個中橫線,可以將自定義參數傳遞給 webpack,例如:npm run build -- --colors

安裝

在開始之前,讓我們對項目做一個小的修改:

dist/index.html

  <!doctype html>
  <html>
    <head>
-    <title>Getting Started</title>
+    <title>Asset Management</title>
    </head>
    <body>
      <script src="./bundle.js"></script>
    </body>
  </html>

加載 CSS

爲了從 JavaScript 模塊中 import 一個 CSS 文件,你需要在 module 配置中 安裝並添加 style-loader 和 css-loader

npm install --save-dev style-loader css-loader

webpack.config.js

  const path = require('path');

  module.exports = {
    entry: './src/index.js',
    output: {
      filename: 'bundle.js',
      path: path.resolve(__dirname, 'dist')
    },
+   module: {
+     rules: [
+       {
+         test: /\.css$/,
+         use: [
+           'style-loader',
+           'css-loader'
+         ]
+       }
+     ]
+   }
  };

webpack 根據正則表達式,來確定應該查找哪些文件,並將其提供給指定的 loader。在這種情況下,以 .css 結尾的全部文件,都將被提供給 style-loader 和 css-loader

這使你可以在依賴於此樣式的文件中 import './style.css'。現在,當該模塊運行時,含有 CSS 字符串的 <style> 標籤,將被插入到 html 文件的 <head> 中。

我們嘗試一下,通過在項目中添加一個新的 style.css 文件,並將其導入到我們的 index.js 中:

project

  webpack-demo
  |- package.json
  |- webpack.config.js
  |- /dist
    |- bundle.js
    |- index.html
  |- /src
+   |- style.css
    |- index.js
  |- /node_modules

src/style.css

.hello {
  color: red;
}

src/index.js

  import _ from 'lodash';
+ import './style.css';

  function component() {
    var element = document.createElement('div');

    // lodash 是由當前 script 腳本 import 導入進來的
    element.innerHTML = _.join(['Hello', 'webpack'], ' ');
+   element.classList.add('hello');

    return element;
  }

  document.body.appendChild(component());

現在運行構建命令:

npm run build

Hash: 9a3abfc96300ef87880f
Version: webpack 2.6.1
Time: 834ms
    Asset    Size  Chunks                    Chunk Names
bundle.js  560 kB       0  [emitted]  [big]  main
   [0] ./~/lodash/lodash.js 540 kB {0} [built]
   [1] ./src/style.css 1 kB {0} [built]
   [2] ./~/css-loader!./src/style.css 191 bytes {0} [built]
   [3] ./~/css-loader/lib/css-base.js 2.26 kB {0} [built]
   [4] ./~/style-loader/lib/addStyles.js 8.7 kB {0} [built]
   [5] ./~/style-loader/lib/urls.js 3.01 kB {0} [built]
   [6] (webpack)/buildin/global.js 509 bytes {0} [built]
   [7] (webpack)/buildin/module.js 517 bytes {0} [built]
   [8] ./src/index.js 351 bytes {0} [built]

再次在瀏覽器中打開 index.html,你應該看到 Hello webpack 現在的樣式是紅色。要查看 webpack 做了什麼,請檢查頁面(不要查看頁面源代碼,因爲它不會顯示結果),並查看頁面的 head 標籤。它應該包含我們在 index.js 中導入的 style 塊元素。

此時目錄結構:

修改過配置文件:webpack.config.js

執行:npx webpack --config webpack.config.js

請注意,在多數情況下,你也可以進行 CSS 分離,以便在生產環境中節省加載時間。最重要的是,現有的 loader 可以支持任何你可以想到的 CSS 處理器風格 - postcsssass 和 less 等。

加載圖片

假想,現在我們正在下載 CSS,但是我們的背景和圖標這些圖片,要如何處理呢?使用 file-loader,我們可以輕鬆地將這些內容混合到 CSS 中:

npm install --save-dev file-loader

webpack.config.js

  const path = require('path');

  module.exports = {
    entry: './src/index.js',
    output: {
      filename: 'bundle.js',
      path: path.resolve(__dirname, 'dist')
    },
    module: {
      rules: [
        {
          test: /\.css$/,
          use: [
            'style-loader',
            'css-loader'
          ]
        },
+       {
+         test: /\.(png|svg|jpg|gif)$/,
+         use: [
+           'file-loader'
+         ]
+       }
      ]
    }
  };

現在,當你 import MyImage from './my-image.png',該圖像將被處理並添加到 output 目錄,_並且_ MyImage 變量將包含該圖像在處理後的最終 url。當使用 css-loader 時,如上所示,你的 CSS 中的 url('./my-image.png') 會使用類似的過程去處理。loader 會識別這是一個本地文件,並將 './my-image.png' 路徑,替換爲輸出目錄中圖像的最終路徑。html-loader 以相同的方式處理 <img src="./my-image.png" />

我們向項目添加一個圖像,然後看它是如何工作的,你可以使用任何你喜歡的圖像:

project

  webpack-demo
  |- package.json
  |- webpack.config.js
  |- /dist
    |- bundle.js
    |- index.html
  |- /src
+   |- icon.png
    |- style.css
    |- index.js
  |- /node_modules

src/index.js

  import _ from 'lodash';
  import './style.css';
+ import Icon from './icon.png';

  function component() {
    var element = document.createElement('div');

    // Lodash,現在由此腳本導入
    element.innerHTML = _.join(['Hello', 'webpack'], ' ');
    element.classList.add('hello');

+   // 將圖像添加到我們現有的 div。
+   var myIcon = new Image();
+   myIcon.src = Icon;
+
+   element.appendChild(myIcon);

    return element;
  }

  document.body.appendChild(component());

src/style.css

  .hello {
    color: red;
+   background: url('./icon.png');
  }

讓我們重新構建,並再次打開 index.html 文件:

npm run build

Hash: 854865050ea3c1c7f237
Version: webpack 2.6.1
Time: 895ms
                               Asset     Size  Chunks                    Chunk Names
5c999da72346a995e7e2718865d019c8.png  11.3 kB          [emitted]
                           bundle.js   561 kB       0  [emitted]  [big]  main
   [0] ./src/icon.png 82 bytes {0} [built]
   [1] ./~/lodash/lodash.js 540 kB {0} [built]
   [2] ./src/style.css 1 kB {0} [built]
   [3] ./~/css-loader!./src/style.css 242 bytes {0} [built]
   [4] ./~/css-loader/lib/css-base.js 2.26 kB {0} [built]
   [5] ./~/style-loader/lib/addStyles.js 8.7 kB {0} [built]
   [6] ./~/style-loader/lib/urls.js 3.01 kB {0} [built]
   [7] (webpack)/buildin/global.js 509 bytes {0} [built]
   [8] (webpack)/buildin/module.js 517 bytes {0} [built]
   [9] ./src/index.js 503 bytes {0} [built]

如果一切順利,和 Hello webpack 文本旁邊的 img 元素一樣,現在看到的圖標是重複的背景圖片。如果你檢查此元素,你將看到實際的文件名已更改爲像 5c999da72346a995e7e2718865d019c8.png 一樣。這意味着 webpack 在 src 文件夾中找到我們的文件,併成功處理過它!

合乎邏輯下一步是,壓縮和優化你的圖像。查看 image-webpack-loader 和 url-loader,以瞭解更多關於如果增強加載處理圖片功能。

加載字體

那麼,像字體這樣的其他資源如何處理呢?file-loader 和 url-loader 可以接收並加載任何文件,然後將其輸出到構建目錄。這就是說,我們可以將它們用於任何類型的文件,包括字體。讓我們更新 webpack.config.js 來處理字體文件:

webpack.config.js

  const path = require('path');

  module.exports = {
    entry: './src/index.js',
    output: {
      filename: 'bundle.js',
      path: path.resolve(__dirname, 'dist')
    },
    module: {
      rules: [
        {
          test: /\.css$/,
          use: [
            'style-loader',
            'css-loader'
          ]
        },
        {
          test: /\.(png|svg|jpg|gif)$/,
          use: [
            'file-loader'
          ]
        },
+       {
+         test: /\.(woff|woff2|eot|ttf|otf)$/,
+         use: [
+           'file-loader'
+         ]
+       }
      ]
    }
  };

在項目中添加一些字體文件:

project

  webpack-demo
  |- package.json
  |- webpack.config.js
  |- /dist
    |- bundle.js
    |- index.html
  |- /src
+   |- my-font.woff
+   |- my-font.woff2
    |- icon.png
    |- style.css
    |- index.js
  |- /node_modules

通過配置好 loader 並將字體文件放在合適的地方,你可以通過一個 @font-face 聲明引入。本地的 url(...)指令會被 webpack 獲取處理,就像它處理圖片資源一樣:

src/style.css

+ @font-face {
+   font-family: 'MyFont';
+   src:  url('./my-font.woff2') format('woff2'),
+         url('./my-font.woff') format('woff');
+   font-weight: 600;
+   font-style: normal;
+ }

  .hello {
    color: red;
+   font-family: 'MyFont';
    background: url('./icon.png');
  }

現在讓我們重新構建來看看 webpack 是否處理了我們的字體:

npm run build

Hash: b4aef94169088c79ed1c
Version: webpack 2.6.1
Time: 775ms
                                Asset     Size  Chunks                    Chunk Names
 5c999da72346a995e7e2718865d019c8.png  11.3 kB          [emitted]
11aebbbd407bcc3ab1e914ca0238d24d.woff   221 kB          [emitted]
                            bundle.js   561 kB       0  [emitted]  [big]  main
   [0] ./src/icon.png 82 bytes {0} [built]
   [1] ./~/lodash/lodash.js 540 kB {0} [built]
   [2] ./src/style.css 1 kB {0} [built]
   [3] ./~/css-loader!./src/style.css 420 bytes {0} [built]
   [4] ./~/css-loader/lib/css-base.js 2.26 kB {0} [built]
   [5] ./src/MyFont.woff 83 bytes {0} [built]
   [6] ./~/style-loader/lib/addStyles.js 8.7 kB {0} [built]
   [7] ./~/style-loader/lib/urls.js 3.01 kB {0} [built]
   [8] (webpack)/buildin/global.js 509 bytes {0} [built]
   [9] (webpack)/buildin/module.js 517 bytes {0} [built]
  [10] ./src/index.js 503 bytes {0} [built]

重新打開 index.html 看看我們的 Hello webpack 文本顯示是否換上了新的字體。如果一切順利,你應該能看到變化。

加載數據

此外,可以加載的有用資源還有數據,如 JSON 文件,CSV、TSV 和 XML。類似於 NodeJS,JSON 支持實際上是內置的,也就是說 import Data from './data.json' 默認將正常運行。要導入 CSV、TSV 和 XML,你可以使用 csv-loader 和 xml-loader。讓我們處理這三類文件:

npm install --save-dev csv-loader xml-loader

webpack.config.js

  const path = require('path');

  module.exports = {
    entry: './src/index.js',
    output: {
      filename: 'bundle.js',
      path: path.resolve(__dirname, 'dist')
    },
    module: {
      rules: [
        {
          test: /\.css$/,
          use: [
            'style-loader',
            'css-loader'
          ]
        },
        {
          test: /\.(png|svg|jpg|gif)$/,
          use: [
            'file-loader'
          ]
        },
        {
          test: /\.(woff|woff2|eot|ttf|otf)$/,
          use: [
            'file-loader'
          ]
        },
+       {
+         test: /\.(csv|tsv)$/,
+         use: [
+           'csv-loader'
+         ]
+       },
+       {
+         test: /\.xml$/,
+         use: [
+           'xml-loader'
+         ]
+       }
      ]
    }
  };

給你的項目添加一些數據文件:

project

  webpack-demo
  |- package.json
  |- webpack.config.js
  |- /dist
    |- bundle.js
    |- index.html
  |- /src
+   |- data.xml
    |- my-font.woff
    |- my-font.woff2
    |- icon.png
    |- style.css
    |- index.js
  |- /node_modules

src/data.xml

<?xml version="1.0" encoding="UTF-8"?>
<note>
  <to>Mary</to>
  <from>John</from>
  <heading>Reminder</heading>
  <body>Call Cindy on Tuesday</body>
</note>

現在,你可以 import 這四種類型的數據(JSON, CSV, TSV, XML)中的任何一種,所導入的 Data 變量將包含可直接使用的已解析 JSON:

src/index.js

  import _ from 'lodash';
  import './style.css';
  import Icon from './icon.png';
+ import Data from './data.xml';

  function component() {
    var element = document.createElement('div');

    // Lodash, now imported by this script
    element.innerHTML = _.join(['Hello', 'webpack'], ' ');
    element.classList.add('hello');

    // Add the image to our existing div.
    var myIcon = new Image();
    myIcon.src = Icon;

    element.appendChild(myIcon);

+   console.log(Data);

    return element;
  }

  document.body.appendChild(component());

當你打開 index.html 並查看開發者工具中的控制檯,你應該能夠看到你導入的數據被打印在了上面!

在使用 d3 等工具來實現某些數據可視化時,預加載數據會非常有用。我們可以不用再發送 ajax 請求,然後於運行時解析數據,而是在構建過程中將其提前載入並打包到模塊中,以便瀏覽器加載模塊後,可以立即從模塊中解析數據。

全局資源

上述所有內容中最出色之處是,以這種方式加載資源,你可以以更直觀的方式將模塊和資源組合在一起。無需依賴於含有全部資源的 /assets 目錄,而是將資源與代碼組合在一起。例如,類似這樣的結構會非常有用:

- |- /assets
+ |– /components
+ |  |– /my-component
+ |  |  |– index.jsx
+ |  |  |– index.css
+ |  |  |– icon.svg
+ |  |  |– img.png

這種配置方式會使你的代碼更具備可移植性,因爲現有的統一放置的方式會造成所有資源緊密耦合在一起。假如你想在另一個項目中使用 /my-component,只需將其複製或移動到 /components 目錄下。只要你已經安裝了任何擴展依賴(external dependencies),並且你已經在配置中定義過相同的 loader,那麼項目應該能夠良好運行。

但是,假如你無法使用新的開發方式,只能被固定於舊有開發方式,或者你有一些在多個組件(視圖、模板、模塊等)之間共享的資源。你仍然可以將這些資源存儲在公共目錄(base directory)中,甚至配合使用 alias 來使它們更方便 import 導入

回退處理

對於接下來的指南,我們無需使用本指南中所有用到的資源,因此我們會進行一些清理工作,以便爲下一部分指南中的管理輸出章節做好準備:

project

  webpack-demo
  |- package.json
  |- webpack.config.js
  |- /dist
    |- bundle.js
    |- index.html
  |- /src
-   |- data.xml
-   |- my-font.woff
-   |- my-font.woff2
-   |- icon.png
-   |- style.css
    |- index.js
  |- /node_modules

webpack.config.js

  const path = require('path');

  module.exports = {
    entry: './src/index.js',
    output: {
      filename: 'bundle.js',
      path: path.resolve(__dirname, 'dist')
    },
-   module: {
-     rules: [
-       {
-         test: /\.css$/,
-         use: [
-           'style-loader',
-           'css-loader'
-         ]
-       },
-       {
-         test: /\.(png|svg|jpg|gif)$/,
-         use: [
-           'file-loader'
-         ]
-       },
-       {
-         test: /\.(woff|woff2|eot|ttf|otf)$/,
-         use: [
-           'file-loader'
-         ]
-       },
-       {
-         test: /\.(csv|tsv)$/,
-         use: [
-           'csv-loader'
-         ]
-       },
-       {
-         test: /\.xml$/,
-         use: [
-           'xml-loader'
-         ]
-       }
-     ]
-   }
  };

src/index.js

  import _ from 'lodash';
- import './style.css';
- import Icon from './icon.png';
- import Data from './data.xml';
-
  function component() {
    var element = document.createElement('div');
-
-   // Lodash,現在通過 script 標籤導入
    element.innerHTML = _.join(['Hello', 'webpack'], ' ');
-   element.classList.add('hello');
-
-   // 將圖像添加到我們已有的 div 中。
-   var myIcon = new Image();
-   myIcon.src = Icon;
-
-   element.appendChild(myIcon);
-
-   console.log(Data);

    return element;
  }

  document.body.appendChild(component());

修改目錄分類:

配置代碼:

const path = require('path');

module.exports = {
	entry: './src/script/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  module:{
  	rules:[
  	{
  		test:/\.css$/,
  		use:[
  		'style-loader',
  		'css-loader'
  		]
  	},
  	{
  		test:/\.(png|svg|jpg|gif)$/,
  		use:[
  		'file-loader'
  		]
  	}
  	]
  },
  devServer: {
  	contentBase: path.join(__dirname, "dist"),
  	compress: true,
  	port: 9000
}
};

script/index.js

import _ from 'lodash';
// import './style.css';
// import Icon from './a1.jpg'
import '../css/style.css';
import Icon from '../pic/a1.jpg'


function component() {
  var element = document.createElement('div');

  // Lodash(目前通過一個 script 腳本引入)對於執行這一行是必需的
  // Lodash, currently included via a script, is required for this line to work
  // Lodash, now imported by this script
  element.innerHTML = _.join(['Hello', 'webpack'], ' ');
  element.classList.add("hello");

  var myIcon=new Image();
  myIcon.src=Icon;

  elment.appendChild(myIcon);

  return element;
}

document.body.appendChild(component());

css/style.css

.hello{
	color:red;
	background: url('../pic/a1.jpg');
}

保證路徑修改正確:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章