標籤:連結 use man 常用 並發 bind mil nodejs 環境變數
webpack說容易也容易,說難也難,主要還是看個人,想學到什麼樣的程度,很多公司可能要求僅僅是會用就行,但是也有一些公司要求比較高,要懂一些底層的原理,所以還是要花一些時間的,看個人需求。這篇僅僅是做了一些總結,都是來自官網,便於複習。
一,先理解webpack的概念:
官網上:webpack 是一個現代 JavaScript 應用程式的模組打包器(module bundler)。當 webpack 處理應用程式時,它會遞迴地構建一個依賴關係圖(dependency graph),其中包含應用程式需要的每個模組,然後將所有這些模組打包成少量的 bundle - 通常只有一個,由瀏覽器載入。
這裡補充一下,webpack和gulp的差異:
gulp是一種前端自動化構建工具,task runner,它的核心功能是:
1,task的定義和組織
2,基於檔案的stream構建
3,外掛程式體系
webpack是module bundler,模組打包器,核心功能是:
1,按照模組的依賴構建目標檔案
2,loader 體系支援不同的模組
3,外掛程式體系提供更多額外的功能
原作者連結:https://www.zhihu.com/question/45536395?sort=created,這篇寫得很好,總結了很多
關於gulp的使用,請見gulp的學習日誌;
二,核心概念(entry,output,loader,plugins)
1,entry和context
context的作用是webpack會先從context配置的路徑下檢索entry檔案;
如:
const config = {
context: path.resolve(‘./src‘), //path.resolve([from...],to),將to參數解析為絕對路徑,path是node模組
entry: ‘index.js‘
}
index.js檔案放在src目錄下;
webpack會建立一個由應用程式所有依賴構成的關係圖(dependency graph),這個圖的起點就是entry point,入口檔案,從哪裡開始,可以為單個入口,也可以為多個入口,文法可以是字串,可以是對象,也可以是數組,對象的可擴充性較高
單個入口:
const config = {
entry: "./index.js‘ //字串文法
};
module.exports = config;
等同於
const config = {
entry: {
main: "./index.js" //對象文法
}
};
module.exports = config;
也可以寫多頁面
const config = { entry: { pageOne: ‘./src/pageOne/index.js‘, pageTwo: ‘./src/pageTwo/index.js‘, pageThree: ‘./src/pageThree/index.js‘
}};
每一個key會是chunk的名稱
2,output
入口起點可以多個,但是輸出配置只有一個
兩個必須的屬性:
filename:輸出檔案名
path:輸出目錄,必須是絕對路徑,否則會報錯。
入口起點單個,最簡單的例子:
const config = { output: { filename: ‘bundle.js‘, path: ‘/home/proj/public/assets‘ }};
如果多個入口起點
const config = {
output: {
filename: ‘[name].js‘,
path: __dirname + ‘/dist‘ //__dirname表示目前的目錄
}
}
屬性publicPath表示指定資源檔引用的目錄,並不表示path前面可以省略publicpath裡面定義的路徑,比如
output: {
publicPath: ‘/dist‘,
path: path.resolve(‘./dist/js‘),
filename: ‘bundle.js‘
},
output.chunkFilename是做什麼的? (深惡痛絕,參加面試的時候問到了這個問題,一臉懵逼,聽過但不懂幹嘛的-。-)
此選項決定了非入口chunk檔案的名稱,可取值在下面的filename裡
(關於output.filename:
1,對於單個入口起點,filename就是一個靜態string,
filename: "bundle.js"
2,如果不是單個入口,為了區分不同的bundle,需要用下面中的一種替換方式來賦予每一個bundle唯一名稱
filename: ‘[name].bundle.js‘
使用內部chunk id
filename: ‘[id].bundle.js‘
使用每次構建過程中,唯一的hash產生
filename: ‘[name].[hash].bundle.js‘
使用基於每個chunk內容的hash
filename: ‘[chunkhash].bundle.js‘)
output.hotUpdateChunkFilename:自訂熱更新chunk的檔案名稱,可選值見上面filename,沒必要修改這個值,預設就行
output還有一些其他屬性,這裡不一一介紹了,詳見官網
3,loader,
對模組的原始碼進行轉換,可以在import或載入的時候(打包前)預先處理檔案,有點類似於task,在webpack2.0版本中,寫法如下:
module: {
rules: [
{
test: /\.txt$/, //test用來識別出應該被對應的loader進行轉換的檔案,用正則寫法
use: ‘raw-loader‘ //use用來轉換檔,並且使其能夠被添加到dependency graph中,並最終添加到bundle中,注意webpack2裡面loader必須寫全,webpack1中loader可以唯寫‘-’前面的,但是2裡面會報錯
}
]
}
我們也可以給use配置多個loader:
module: {
rules: [
{
test: /\.css$/,
use: [
{loader: ‘style-loader‘},
{
loader: ‘css-loader‘,
options: {
modules: true
}
}
]
}
]
}
同樣我們可以通過CLI使用loader,直接敲命令:
webpack --module-bind jade-loader --module-bind ‘css=style-loader!css-loader‘
這會對.jade檔案使用jade-loader,對.css檔案使用style-loader和css-loader
每個rule分為三部分:條件,結果和嵌套規則:
1,條件:有兩種輸入值,resource:請求檔案的絕對路徑,相關屬性是test,include,exclude,resource
issuer:被請求資源的模組檔案的絕對路徑,相關屬性是issuer
這兩種輸入值解釋一下,從app.js裡面匯入"./style.css",那麼resource就是/path/to/style.css,而issure就是/path/to/app.js
2,結果:有兩種輸入值,應用的loader:應用在resource上的loader數組,
Parser選項:用於為模組建立解析器的選項對象。
影響loader的屬性:loader,options,use,query,loaders
3,嵌套規則:屬性rules,oneOf制定嵌套規則
rule的其他屬性,詳見官方文檔
4,plugin
外掛程式的目的是解決loader無法實現的事
用法,向plugins屬性傳入new執行個體,下面我會列舉一些常用的plugin
const HtmlWebpackPlugin = require(‘html-webpack-plugin‘);
const cleanWebpackPlugin = require(‘clean-webpack-plugin‘);
const webpack = require(‘webpack‘)
plugins: [ new HtmlWebpackPlugin ({
title: ‘Hot Module Replacement‘ //關於HtmlWebpackPlugin的參數配置,參考這個作者連結http://www.cnblogs.com/haogj/p/5160821.html
}),
new webpack.HotModuleReplacementPlugin(), //模組熱替換,
new cleanWebpackPlugin([‘dist‘]) //清除dist檔案夾
]
5,其他配置:
devtool:開發環境下推薦用“cheap-module-eval-source-map”,生產環境下推薦用“source-map”,其他的選項見官方文檔
webpack-dev-server: 這個不多說,就是本地起一個服務然後監聽檔案變化
webpack -p 等同於 webpack --optimize --define process.env.NODE_ENV="‘production‘",會執行如下步驟:
使用UglifyJsPlugin進行JS檔案壓縮,運行LoaderOptionsPlugin(主要是用來將webpack1遷移到webpack2上),設定NodeJS環境變數,觸發某些package包,以不同的方式進行編譯
devServer:配置項見官方文檔,比較多,常用的幾個:
devServer: {
contentBase: path.resolve(__dirname, ‘dist‘),
compress: true, //一切服務都啟用gzip壓縮
port: 9000,
color: true,
hot: true,
hotOnly: true,
open: true
}
6,Manifest
概念:當編譯器開始執行、解析和映射應用程式時,它會保留所有模組的詳細要點,這個資料集合就是Manifest
runtime:在模組互動時,串連模組所需的載入和解析邏輯,包括瀏覽器中已經載入的模組的串連,以及懶載入模組的執行邏輯。
當完成打包並發送給瀏覽器時,會在運行時通過Manifest來解析和載入模組,此時import或require已經轉換成了__webpack_require__方法,此方法指向模組標識符,通過使用Manifest中的資料,runtime將能夠查詢模組標識符,檢索出背後對應的模組。
7,target
webpack提供了多種構建目標target,表明了用於哪種環境下的javascript
node:編譯為類Node.js環境可用
web:編譯為類瀏覽器環境下可用(預設)
。。。。。。
webpack2學習日誌