1.概念:
本質上, webpack是一個現代JavaScript應用程序的靜態模塊打包器,當webpack處理應用程序時,它會遞歸地構建一個依賴關系圖,其中包含應用程序需要的每個模塊,然后將所有這些模塊打包成一個或多個bundle;
四個核心概念:
(1)入口(entry): 指 示w ebpack應該使用哪個模塊,來作為構建起內部依賴圖的開始;進入入口起點后,webpack會找出有哪些模塊和庫是入口起點(直接和間接)依賴的;
每個依賴隨機被處理,最后輸出到稱之為bundles的文件中;
可以 通過在webpack配置中配置entry屬性,來指定一個入口起點(或多個入口起點),默認值是./src
文件:webpack.config.js
module.exports = {entry: './path/to/my/entry/file.js'};
(2)輸出(output): output屬性告訴webpack在哪里輸出它所創建的bundles,以及如何命名這些文件,默認值為./dist。
基本上,整個應用程序結構,都會被編譯到你指定的輸出路徑的文件夾中,你可以 通過在配置中指定一個?output字段,來配置這些處理過程:
const path = require('path');? //Node.js核心模塊,用于操作文件路徑module.exports = {entry: './path/to/my/entry/file.js',output: {path: path.resolve(__dirname, 'dist'),filename: 'my-first-webpack.bundle.js'}};
(3)loader:讓webpack能夠去處理那些非JavaScript文件(webpack自身只理解JavaScript). loader可以將所有類型的文件轉換為webpack能夠處理的有效模塊,然后就可以利用webpack的打包能力,對它們進行處理;
本質上,webpack?loader將所有類型的文件,轉換為應用程序的依賴圖(和最終的bundle)可以直接引用的模塊
在更高層面,在webpack的配置好中loader有兩個小目標:
*****test屬性,用于 標識出應該被對應的loader進行轉換的某個或某些文件
*****use屬性,表示進行轉換時,應該使用哪個loader
const path = require('path');const config = {output: {filename: 'my-first-webpack.bundle.js'},module: {? ? ? ? ? ? //告訴webpack編譯器:嘿,webpack編譯器,當你碰到在? require()/import?語句中被解析為? ".txt"的路徑時,在你對它打包之前,先使用raw-loader轉換一下rules: [{ test: /\.txt$/, use: 'raw-loader' }? ?//重要的是要記得,在webpack配置中定義的loader時,要定義的module.rules中,而不是rules]}};module.exports = config;
(4)插件(plugins):插件可以執行的范圍是:從打包優化和壓縮,一直到重新定義環境中的變量; 插件接口功能極其強大,可以用來處理各種各樣的任務;
想要使用一個插件,你 只需要?require()它,然后把它添加到?plugins數組中,這時就需要通過使用? ?new?操作符來創建它的一個實例
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通過 npm 安裝
const webpack = require('webpack'); // 用于訪問內置插件const config = {module: {rules: [{ test: /\.txt$/, use: 'raw-loader' }]},plugins: [new HtmlWebpackPlugin({template: './src/index.html'})]};module.exports = config;
2.webpack構建流程:
(1)解析webpack配置參數, 合并從shell傳入和webpack.config.js文件里配置的參數,生產最后的配置結果
(2)注冊所有配置的插件,好讓 插件監聽webpack構建生命周期的事件節點,以做出對應的反應
(3)從配置的entry入口文件開始解析文件構建AST語法樹( 以樹狀的形式表現 編程語言 的語法結構, 樹上的每個節點都表示源代碼中的一種結構),找出每個文件所依賴的文件,遞歸下去
(4)在解析文件遞歸的過程中根據文件類型和loader配置找出合適的loader用來對文件進行轉換
(5)遞歸完后得到每個文件的最終結果,根據entry配置生成代碼塊chunk
(6)輸出所有chunk到文件系統
3.單頁應用:
(1)一個單頁應用需要配置一個entry?指明執行入口,webpack會為entry?生成一個包含這個入口所有依賴的chunk,但要讓它在瀏覽器里跑起來還需要一個HTML文件來加載chunk生成的js文件,如果提取出了css還需要讓HTML文件引入提取出的css, web-webpack-plugin里的WebPlugin可以自動完成這些工作;
const { WebPlugin } = require('web-webpack-plugin');
module.exports = {entry: {app: './src/doc/index.js',},plugins: [// 一個WebPlugin對應生成一個html文件new WebPlugin({//輸出的html文件名稱filename: 'index.html',//這個html依賴的`entry`requires: ['app'],? ? //指明這個HTML依賴哪些entry,entry生成的js和css會自動注入到HTML里}),],
};
(2)可以配置這些資源的注入方式,支持如下屬性:
*****_dist :只是在生產環境下才引入該資源
*****_dev :?只有在開發環境下才引入該資源
*****_inline:?把該資源的內容潛入到html里
*****_ie :只有IE瀏覽器才需要引入的資源
new WebPlugin({filename: 'index.html',requires: {app:{_dist:true,_inline:false,}},
}),
4.一個項目管理多個單頁應用:
(1)一般項目里會包含多個單頁應用,雖然多個單頁應用也可以合并成一個但是這樣做會導致用戶沒訪問的部分也加載了,如果項目里有很多個單頁應用,為每個單頁應用配置一個entry?和 WebPlugin?如果項目又新增一個單頁應用,又去新增webpack配置?這樣做太麻煩了, web-webpack-plugin里的AutoWebPlugin可以方便的解決這些問題;
module.exports = {plugins: [// 所有頁面的入口目錄new AutoWebPlugin('./src/'),]
};
AutoWebPlugin會把? ./src/目錄下所有每個文件夾作為一個單頁頁面的入口, 自動為所有的頁面入口配置一個WebPlugin輸出對應的html。要新增一個頁面就在 ./src/下新建一個文件夾包含這個單頁應用所依賴的代碼,A