webpack3中文版使用參考文檔--全面解析webpack.config.js


Webpack目前官方發布的最新版本是3.1.0,相對於2.0的版本,在語法上沒有變動,只是新增了功能。使用webpack,需要事先安裝node.js,並對node.js生態有一些基本的了解,比如(npm init 初始化項目,npm install 安裝一個包等等)。使用webpack通常有兩種方式:1. 命令行方式(CLI) , 2 script方式(推薦)。 兩種方式都需要理解webpack概念。

概念

webpack is a module bundler for modern JavaScript applications. When webpack processes your application, it recursively builds a dependency graph that includes every module your application needs, then packages all of those modules into a small number of bundles - often only one - to be loaded by the browser.

webpack是時下很火的js模塊化的打包工具。當用webpack處理你的應用時,它會遞歸的構建每個模塊的依賴關系圖,然后把所有的這些依賴模塊打包到一個由數個小塊組成的文件中--通常只有一個(將被瀏覽器加載)

It is incredibly configurable, but to get started you only need to understand Four Core Concepts: entry, output, loaders, and plugins.

雖然它是高度可配置的,但是初步使用你只需要理解下面這四個核心概念:入口,輸出,加載器,插件。默認情況下,所有這些配置項,都保存在項目根目錄下一個名為webpack.config.js的文件中。

一. 入口 (entry) 

The entry point tells webpack where to start and follows the graph of dependencies to know what to bundle. You can think of your application's entry point as the contextual root or the first file to kick off your app.

所謂的入口,就是告訴webpack從哪里開始並通過依賴關系圖得知要哪些文件要打包。你可以理解為應用程序最先讀取的文件。讀取這個文件之后,就會產生一個模塊依賴關系圖,那么當前這個文件,就是依賴關系的根。

webpack.config.js

module.exports = {
  entry: './path/to/my/entry/file.js'
};

上例告訴webpack從./path/to/my/entry/file.js開始打包,這是最簡單的一種入口形式,實際上,它是下面這種形式的簡寫

module.exports = {
    entry : {
        main : './path/to/my/entry/file.js'
   }  
}

entry 還可以是數組的方式

module.exports = {
  entry: ['./path/to/my/entry/file.js']
};

這對於不想在js中引入css的情況非常有用,比如:

module.exports = {
  entry: ['./path/to/my/entry/file.js','./path/to/my/entry/file.css']
};

如果是多頁應用或者想要提取公共代碼(CommonsChunkPlugin)的話,就需要使用下面這種入口方式:

module.exports = {
   entry: {
    pageOne: './src/pageOne/index.js',
    pageTwo: './src/pageTwo/index.js',
    pageThree: './src/pageThree/index.js'
  }
}     

 當然,這里也可以使用數組的形式,同時引入樣式或其它文件

module.exports = {
  entry: {
    pageOne: ['./src/pageOne/index.js','./src/pageOne/index.css'],
    pageTwo: ['./src/pageTwo/index.js'],
    pageThree: ['./src/pageThree/index.js']
  }
}

以上就是關於入口這個概念和配置的全部內容了,更詳細的介紹請移步官方網站關於入口的擴展介紹 。 除了要告訴webpack要從哪個文件開始打包之外,還要告訴它打包生成的文件存放在哪個位置。於是就有了輸出的配置。

二. 輸出 (output)

webpack的output屬性就是告訴webpack怎么對待這些打包的代碼。

Configuring the output configuration options tell webpack how to write the compiled files to disk. Note that, while there can be multiple entry points, only one output configuration is specified.

 配置output屬性就是告訴webpack把編譯后的文件寫在磁盤的哪個地方。注意一點,雖然入口中可以配置成多個文件的形式,但是輸出只能指定一個。

--- 打包之后資源,並不總是寫在磁盤上,也可能是在內存中,比如使用webpack-dev-server的時候。(譯者注)

webpack.config.js

const path = require('path');

module.exports = {
  entry: './path/to/my/entry/file.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'my-first-webpack.bundle.js'
  }
};

 output有兩個屬性是必須的。

 1. path 輸出路徑

  • An absolute path to your preferred output directory.  通常是絕對路徑。

 2. filename 文件名

     當入口是多個文件的時候,可以用變量[name]代替固定的名字。這里的name變量,對應entry中的key. ( 對於entry:配置成字符串的時候,輸出的文件名就是main,如果不明白,查看前面入口部分的介紹)

module.exports = {
 entry: {
    app: './src/app.js',
    search: './src/search.js'
  },
  output: {
    filename: '[name].js',
    path: __dirname + '/dist'
  }

}

   在filename屬性中,除了[name]之外,還可以用[hash],[contenthash]等內置變量, Tips ! [hash:8] 截取hash前8位

3. publicPath 虛擬路徑

  如果你有一個域名或打算用CDN,可以使用這個配置,如果你不知道,或暫時不打算用,可以不寫。

output: {
  path: "/home/proj/cdn/assets/",
  publicPath: "http://cdn.example.com/assets/",
  filename:'[name].js'
}

 注意:如果配置了publicPath屬性,那么本地資源路徑,都會被替換成publicPath所指定的地址 (譯者注)

 三、加載器

Loaders are transformations that are applied on the source code of a module. They allow you to pre-process files as you import or “load” them. Thus, loaders are kind of like “tasks” in other build tools, and provide a powerful way to handle front-end build steps. Loaders can transform files from a different language (like TypeScript) to JavaScript, or inline images as data URLs. Loaders even allow you to do things like import CSS files directly from your JavaScript modules!

加載器用於將資源代碼轉換成模塊。它允許您在導入或“加載”它們時預處理文件。因此,加載器就像處理各種任務的小工具,它提供一個強大的方法來處理前端構建步驟。加載器可以把不同類型的文件(比如typescript)轉換成javascript 或者把圖片處理成內聯的數據地址(如base64),加載器甚至可以像導入js模塊一樣直接導入樣式文件。

加載器聽起來很歷害的樣子,不過它不能算是webpack的功能,如果要想在項目中導入樣式模塊,需要先安裝樣式的加載器(css-loader), 同樣的,要導入圖片要安裝文件加載器(file-loader)

在命令行中輸入:
npm install --save-dev css-loader
即可安裝樣式加載器,后面跟的參數--save-dev 表示將保存到package.json的開發環境依賴屬性中。對應還有一個--save表示安裝到生產環境。 package.json文件可以通過手工創建,也可用npm init(推薦)
創建。更多關於package.json的介紹請移步這里

 webpack.config.js

module.exports = {
  module: {
    rules: [
      { test: /\.css$/, use: 'css-loader' }
    ]
  }
};

 加載器位於module屬性中(適用於webpack2.0+), rules 是一個數組,里邊可以添加多個加載器(loader).  每一個加載器用對象的方式組織,下面是一個更為復雜的配置

module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          { loader: 'style-loader' },
          {
            loader: 'css-loader',
            options: {
              modules: true
            }
          }
        ]
      }
    ]
  }

 每一個加載器,都有各自對應的配置內容,比如css-loader的詳細配置請移步這里 ,但是不管怎么說,方法都是一樣的。需要指出的事,加載器,除了在webpack.config.js中配置之外,還可以直接在js代碼中用行內加載的方式使用,比如

import Styles from 'style-loader!css-loader?modules!./styles.css'; //多個加載器之間用!進行分隔

不過這種方式寫起來很冗長,不推薦。還有一種方式,也一並提一下,在CLI方式中的使用

webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader'

同樣的冗長,了解一下即可,實際項目中,大多是使用webpack.config.js進行集中配置。

一般來說,一個加載器就可以完成一個任務,比如file-loader 可以加載文件到js的模塊中,可是我們常常發現,加載css到js模塊中,除了使用css-loader之外,常常還有一個或多個附加的伴侶,比如這個style-loader。

這是為什么呢? 這其實是因為樣式的使用有兩種方式,一種是內聯的方式,寫在html的style標簽中,還有一種是外鏈,通過link的方式引用。而我們在開發環境中,css是作為js的模塊打包進js文件中的。而且js要使用樣式,必須在html中插入style標簽,然后把樣式以字符串的形式插入標簽內。所以這里需要用到兩個加載器,首先用css-loader把樣式讀取到js的模塊中,然用style-loader寫入style標簽中。所以也就出現了css-loader和style-loader成對使用的情況。對於同時使用多個加載器的情況,它們的調用順序是從右向左的。也就是說最先使用的要寫在最右邊,對於新式這個例子來說,就是style-loader!css-loader這樣寫。關於style-loader這個加載器,其實它還有一個少被人提起,卻非常有用的功能--熱替換,這部分內容后面再細說

有人不禁要問,既然css可以直接用link的方式使用,為什么不把css打包成獨立的css文件呢?這樣我就不需要用style-loader了,而且把樣式內聯在html中,看着不舒服。好吧,這就不得不引出webpack中的第四個概念了---插件

四、 插件 plugins

They also serve the purpose of doing anything else that a loader cannot do.

插件用於完成一些載器所不能做的事情。

其實這樣解釋不並是很嚴謹,但是插件,確實使的webpack更加強大了。回到前說的獨立樣式的問題,結合插件來做。

先安裝extract-text-webpack-plugin 這個插件

npm install --save-dev extract-text-webpack-plugin

var path = require('path');
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var node_modules_dir = path.resolve(__dirname, '../node_modules');

module.exports = {
    entry: {
        home:'./src/home.es6'
    },
    module: {
        rules:[{
                test:/\.css/,
                use: ExtractTextPlugin.extract({
                  fallback: "style-loader",
                  use: ["css-loader","postcss-loader"]
                })
            }
        ]
    },
    output: {
        path: path.resolve(__dirname,"../dist"),
        filename: 'js/[name][hash:7].js'
    },
    plugins: [
        new ExtractTextPlugin({
            filename: "css/[name].[contenthash].css"
        }),
        new webpack.optimize.UglifyJsPlugin()
    ],
}

 new webpack.optimize.UglifyJsPlugin() //用來壓縮代碼,這個是webpack送的,不需要單獨安裝, new ExtractTextPlugin 用來提取css到一個獨立的樣式文件,這個插件需要自己安裝,還要在loader中進行相應的改動,配合使用才能生效。值得注意的是,這樣一來,就牲犧了css的熱替換能力了。不過無所謂,這個插件一般用在生產環境打包。

Hot Module Replacement  (HMR熱替換) 

這應當屬於webpack中比較高級的內容了,但是在開發中,結合熱替換一起使用,會很方便。最簡單的使用方式是通過 webpack-dev-server --hot

關於這一部分的內容,參考我以前寫的一篇文章。官方介紹移步這里這里需要指出的是,並不是加了--hot就可以實現熱替換,這需要對應的加載器支持“熱替換”才行的。

比如前面說的樣式,style-loader是可以支持熱替換的。而且對於js來說,雖然webpack不需要額外的加載器就可以進模塊化,但是並不支持“熱替換", 如果使用react.js的話,可以用react-hot-loader,如果用Vue的話,可以用vue-loader。 如果該加載器不支持熱替,會降級為自動刷新。因此,熱替換,並不是自動刷新哦。

總結

 webpack3還比較新,如果之前使用webpack2的項目,直接升級到webpack3的話,需要小心了,有些加載器和插件可能不支持webpack3. 比如提取css為獨立文件的插件,就不支持。webpack-dev-server也不支持 (至少在我寫這篇文章的時候還是不支持的),但是不能因噎廢食,新技術最終會取替舊技術,這是行業趨勢。安於現狀,只會被淘汰。webpack的學習最好是自己寫一個簡單項目,把文章提到的和自己學到的loader,plugin都試試。把基本的概念和用法型明白之后,可以安裝別人寫的比較優盤的項目拿來對照學習,比如Vue-cli。看看行業大牛們,是怎么配置webpack的,他們都用了哪些插件和加載器。最后,我也提供一下自己練習的項目,做為本篇的結尾。https://github.com/bjtqti/font-end-boilerplate.git 

 


免責聲明!

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



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