《webpack文件》學習筆記

挖坑埋神經病發表於2018-07-13

webpack

是一個現代 JavaScript 應用程式的靜態模組打包器(module bundler)。當 webpack 處理應用程式時,它會遞迴地構建一個依賴關係圖(dependency graph),其中包含應用程式需要的每個模組,然後將所有這些模組打包成一個或多個 bundle。

  • 入口(entry)
  • 輸出(output)
  • loader
  • 外掛(plugins)

入口

入口起點(entry point)指示 webpack 應該使用哪個模組,來作為構建其內部依賴圖的開始。進入入口起點後,webpack 會找出有哪些模組和庫是入口起點(直接和間接)依賴的。

單個入口簡寫語法:

webpack.config.js

const config = {
  entry: {
    main: './path/to/my/entry/file.js'
  }
};  
複製程式碼

物件語法

1.分離應用程式(app)和第三方庫(vendor)入口

webpack.config.js

const config = {
 entry: {
 app: './src/app.js',
 vendors: './src/vendors.js'
 }
}; 
複製程式碼

2.多頁面應用程式

webpack.config.js

const config = {
 entry: {
 pageOne: './src/pageOne/index.js',
 pageTwo: './src/pageTwo/index.js',
 pageThree: './src/pageThree/index.js'
 }
}; 
複製程式碼

這是我們告訴webpack需要三個獨立分離的依賴圖

輸出

output 屬性告訴 webpack 在哪裡輸出它所建立的 bundles,以及如何命名這些檔案,預設值為 ./dist。基本上,整個應用程式結構,都會被編譯到你指定的輸出路徑的資料夾中。你可以通過在配置中指定一個 output 欄位,來配置這些處理過程。

用法

在 webpack 中配置 output 屬性的最低要求是,將它的值設定為一個物件,包括以下兩點:

  • filename 用於輸出檔案的檔名。
  • 目標輸出目錄 path 的絕對路徑。

webpack.config.js

    const config = {
          output: {
            filename: 'bundle.js',
            path: '/home/proj/public/assets'
          }
        };

    module.exports = config;
複製程式碼

此配置將一個單獨的 bundle.js 檔案輸出到 /home/proj/public/assets 目錄中。

多個入口起點

{
    entry:{
        app:'./src/app.js',
        search:'./src/search.js'
    },
    output:{
        filename:'[name].js',
        path: __dirname + '/dist'
    }
}
//寫入到硬碟:./dist/app.js,./dist/search.js 
複製程式碼

高階進階

使用CDN和資源hash的複雜示例
config.js

output:{
    path:'home/proj/cdn/assets/[hash]',
    publicPath:'http://cdn.example.com/assets/[hash]/'
} 
複製程式碼

在編譯時不知道最終輸出檔案的 publicPath 的情況下,publicPath 可以留空,並且在入口起點檔案執行時動態設定。如果你在編譯時不知道 publicPath,你可以先忽略它,並且在入口起點設定 webpack_public_path

__webpack_public_path__ = myRuntimePublicPath

// 剩餘的應用程式入口
複製程式碼

loader

loader 用於對模組的原始碼進行轉換。loader 可以使你在 import 或"載入"模組時預處理檔案。因此,loader 類似於其他構建工具中“任務(task)”,並提供了處理前端構建步驟的強大方法。loader 可以將檔案從不同的語言(如 TypeScript)轉換為 JavaScript,或將內聯影象轉換為 data URL。loader 甚至允許你直接在 JavaScript 模組中 import CSS檔案!

使用

三種使用loader的方式:

  • 配置(推薦):在 webpack.config.js 檔案中指定 loader。
  • 內聯:在每個 import 語句中顯式指定 loader。(具體看文件)
  • CLI:在 shell 命令中指定它們。 (具體看文件)

配置

module.rules 允許你在 webpack 配置中指定多個 loader。 這是展示 loader 的一種簡明方式,並且有助於使程式碼變得簡潔。同時讓你對各個 loader 有個全域性概覽:

    module:{
            rules:[
                {
                    test:/\.css$/,
                    use:[
                        {loader:'style-loader'},
                        {
                            loader:'css-loader',
                            options:{
                                modules:true
                            }
                        }
                    ]
                }
            ]
        }
    //loader 能夠使用 options 物件進行配置。
複製程式碼

外掛

外掛是 webpack 的支柱功能。webpack 自身也是構建於,你在 webpack 配置中用到的相同的外掛系統之上!

外掛目的在於解決 loader 無法實現的其他事。

用法

由於外掛可以攜帶引數/選項,你必須在 webpack 配置中,向 plugins 屬性傳入 new 例項。

webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin'); //通過 npm 安裝
const webpack = require('webpack'); //訪問內建的外掛
const path = require('path');

const config = {
  entry: './path/to/my/entry/file.js',
  output: {
    filename: 'my-first-webpack.bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        use: 'babel-loader'
      }
    ]
  },
  plugins: [
    new webpack.optimize.UglifyJsPlugin(),
    new HtmlWebpackPlugin({template: './src/index.html'})
  ]
};

module.exports = config;
複製程式碼

配置

因為 webpack 配置是標準的 Node.js CommonJS 模組,你可以做到以下事情:

  • 通過 require(...) 匯入其他檔案
  • 通過 require(...) 使用 npm 的工具函式
  • 使用 JavaScript 控制流表示式,例如 ?: 操作符
  • 對常用值使用常量或變數
  • 編寫並執行函式來生成部分配置

模組

什麼是webpack模組

  • ES2015 import 語句
  • CommonJS require() 語句
  • AMD define 和 require 語句
  • css/sass/less 檔案中的 @import 語句。
  • 樣式(url(...))或 HTML 檔案(<img src=...>)中的圖片連結(image url)

優化路徑

1. resolve.extensions

  在webpack.base.conf.js中,我們可以看到resolve配置,其中的extengsions是一個陣列,如下所示:

extensions: ['.js', '.vue', '.json'],
複製程式碼

  通過這樣的配置,我們在元件中過著路由中應用元件時,就可以更為方便的應用,比如:

import Hello from '@components/Hello';   即Hello.vue這個元件我們不需要新增.vue字尾就可以引用到了,如果不用extensions, 我們就必須要用@components/Hello.vue來引入這個檔案。

2. resolve.alias

  在元件之間相互引用時,可能是下面這樣的:

import Hello from '../src.components/Hello';  
複製程式碼

  其中的路徑是相對於當前頁面的。 但是如果巢狀等更為複雜,那麼寫起來會比較麻煩。但是如果我們通過這樣的配置:

  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@pages': path.join(__dirname, "..", "src", "pages"),
      "@components": path.join(__dirname, "..", "src", "components"),
      // 注意: 靜態資源通過src,不能這麼設定。
      // "@assets": path.join(__dirname, "..", "src", "assets"),
    }
複製程式碼

其中vue$表示引入vue,就可以像下面這麼寫:

import Vue from 'vue'  
複製程式碼

  另外,對於@pages和@components我們就可以直接引用了,而省去了一大堆的複雜應用,另外通過@可以消除歧義。如下所示:

import Hello from '@components/Hello';


import App from '@pages/App'  
複製程式碼

  值得注意的時: 在webpack.config.js中我們不能使用../ 以及./這種形式的路徑方式,而是通過 path.join 和 __dirname 這種形式來表示路徑,否則會報錯。

  另外: 在元件中,我們會引用一些靜態檔案,即static下的檔案, 這時我們就不能用 alias 下的配置了,而必須使用一般的配置方式。

構建目標

因為伺服器和瀏覽器程式碼都可以用 JavaScript 編寫,所以 webpack 提供了多種構建目標(target),你可以在你的 webpack 配置中設定。

用法

要設定 target 屬性,只需要在你的 webpack 配置中設定 target 的值。
webpack.config.js

module.exports = {
  target: 'node'
};  
複製程式碼

在上面例子中,使用 node webpack 會編譯為用於「類 Node.js」環境(使用 Node.js 的 require ,而不是使用任意內建模組(如 fs 或 path)來載入 chunk)。

多個Target

儘管 webpack 不支援向 target 傳入多個字串,你可以通過打包兩份分離的配置來建立同構的庫:
webpack.config.js

var path = require('path');
var serverConfig = {
  target: 'node',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'lib.node.js'
  }
  //…
};

var clientConfig = {
  target: 'web', // <=== 預設是 'web',可省略
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'lib.js'
  }
  //…
};

module.exports = [ serverConfig, clientConfig ];
複製程式碼

上面的例子將在你的 dist 資料夾下建立 lib.js 和 lib.node.js 檔案。

相關文章