webpack 4.x 初級學習記錄
目錄
- webpack 4.x 安裝
- webpack 4.x 基本打包編譯
- webpack 配置
- 概念
- webpack-dev-server
- 安裝
- 基本概念
- 配置webpack.config.js
- 配置package.json
- webpack loader處理
- 安裝
- 配置
- HTML的img標記處理
- CSS 打包分離
- webpack 插件
- 剖析
- 用法
- 配置
- webpack babel
- 安裝
- 配置
- webpack 引入第三方庫
- 安裝
- 使用
首先聲明下,本人不擅長文字表達,文采不行,所以文章中文字較少,請看代碼,初級學習,不足之處請多多指教
GitHub鏈接
webpack 4.x 安裝
- 首先需要在全局中安裝
npm install webpack -g
npm install webpack-cli -g // 與webpack 3.x 的區別
- 接下來打開新的文件夾,創建package.json
npm init
初始化 package.json
文件。
- 局部安裝
npm install webpack --save
npm install webpack-cli --save
webpack 4.x 基本打包編譯
- webpack 3.x 編譯
webpack a.js b.js
# {extry file}出填寫入口文件的路徑,本文中就是上述main.js的路徑, # {destination for bundled file}處填寫打包文件的存放路徑 # 填寫路徑的時候不用添加{} webpack {entry file} {destination for bundled file}
以上就是4版本之前的使用方式,但是這種方式在4版本中就不能使用了,4版本有自己的新的方式
- webpack 4.x 默認打包編譯
為什麽上面要寫默認打包編譯,是因為webpack可以自定義打包編譯配置,我們首先說下默認的打包編譯。
entry: "/src/index.js" // 默認入口文件
output: "/dist/main.js" // 默認輸入文件
上面路徑及文件中,src
和 index.js
需要我們手動去創建,在 index.js
中寫好js代碼即可,其余的 dist
和 main.js
都是由系統自動生成的,並且當你再一次編譯時,會自動的在 dist
中覆蓋同名文件。
而webpack 4.x 的編譯命令也發生變化了,如下所示,分為開發環境和生產環境的命令
webpack --mode development
webpack --mode production
使用命令後,會自動生成文件。
配置 package.json
文件
"scripts": {
"dev": "webpack --mode development",
"build": "webpack --mode production"
}
可以使用 npm ruin dev
和 npm run build
進行執行命令
webpack 配置
概念
本質上,webpack 是一個現代 JavaScript 應用程序的靜態模塊打包器(static module bundler)。在 webpack 處理應用程序時,它會在內部創建一個依賴圖(dependency graph),用於映射到項目需要的每個模塊,然後將所有這些依賴生成到一個或多個bundle。
從 webpack 4.0.0 版本開始,可以不用通過引入一個配置文件打包項目。然而,webpack 仍然還是 高度可配置的,並且能夠很好的滿足需求。
webpack 的核心概念:
- 入口(entry)
- 輸出(output)
- loader
- 插件(plugins)
我們需要在根目錄下創建一個 webpack.config.js
的文件,使用 Commonjs 規範來進行書寫。
入口(entry)
入口起點(entry point)指示 webpack 應該使用哪個模塊,來作為構建其內部依賴圖的開始。進入入口起點後,webpack 會找出有哪些模塊和庫是入口起點(直接和間接)依賴的。
可以通過在 webpack 配置中配置 entry
屬性,來指定一個入口起點(或多個入口起點)。默認值為 ./src
。
module.exports = {
entry: "./src/index.js",
};
entry
屬性的單個入口語法,是下面的簡寫:
module.exports = {
entry: {
main: "./src/index.js",
}
};
當你向
entry
傳入一個數組時會發生什麽?向entry
屬性傳入「文件路徑(file path)數組」將創建“多個主入口(multi-main entry)”。在你想要多個依賴文件一起註入,並且將它們的依賴導向(graph)到一個“chunk”時,傳入數組的方式就很有用。
多個入口文件處理
module.exports = {
entry: {
main: "./src/index.js",
app: ‘./src/app.js‘
}
};
根據經驗:每個 HTML 文檔只使用一個入口起點。 當然也可以使用多個,但是推薦一個使用一個
了解更多
輸出(output)
output
屬性告訴 webpack
在哪裏輸出它所創建的 bundles
,以及如何命名這些文件,默認值為 ./dist
。基本上,整個應用程序結構,都會被編譯到你指定的輸出路徑的文件夾中。你可以通過在配置中指定一個 output
字段,來配置這些處理過程:
const path = require(‘path‘);
module.exports = {
entry: "./src/index.js"
output: {
path: path.resolve(__dirname, ‘dist‘),
filename: ‘bundle.js‘
}
};
當然上面的位置文件名都是可以改變的,可以自定義配置。
在上面的示例中,我們通過 output.filename
和 output.path
屬性,來告訴 webpack bundle
的名稱,以及我們想要 bundle 生成(emit)到哪裏
了解更多
loader
‘
loader 讓 webpack 能夠去處理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以將所有類型的文件轉換為 webpack 能夠處理的有效模塊,然後你就可以利用 webpack 的打包能力,對它們進行處理。
本質上,webpack loader 將所有類型的文件,轉換為應用程序的依賴圖(和最終的 bundle)可以直接引用的模塊。
註意,loader 能夠
import
導入任何類型的模塊(例如 .css 文件),這是 webpack 特有的功能,其他打包程序或任務執行器的可能並不支持。我們認為這種語言擴展是有很必要的,因為這可以使開發人員創建出更準確的依賴關系圖。
在更高層面,在 webpack 的配置中 loader 有兩個目標:
test
屬性,用於標識出應該被對應的 loader 進行轉換的某個或某些文件。use
屬性,表示進行轉換時,應該使用哪個 loader。
const path = require(‘path‘);
const config = {
entry: "./src/index.js"
output: {
path: path.resolve(__dirname, ‘dist‘),
filename: ‘bundle.js‘
},
module: {
rules: [
{ test: /\.txt$/, use: ‘raw-loader‘ }
]
}
};
module.exports = config;
以上配置中,對一個單獨的 module 對象定義了 rules 屬性,裏面包含兩個必須屬性:test 和 use。這告訴 webpack 編譯器(compiler) 如下信息:
“嘿,webpack 編譯器,當你碰到「在 require()/import 語句中被解析為 ‘.txt‘ 的路徑」時,在你對它打包之前,先使用 raw-loader 轉換一下。”
了解更多
插件(plugins)
loader 被用於轉換某些類型的模塊,而插件則可以用於執行範圍更廣的任務。插件的範圍包括,從打包優化和壓縮,一直到重新定義環境中的變量。插件接口功能極其強大,可以用來處理各種各樣的任務。
想要使用一個插件,你只需要 require()
它,然後把它添加到 plugins
數組中。多數插件可以通過選項(option)自定義。你也可以在一個配置文件中因為不同目的而多次使用同一個插件,這時需要通過使用 new
操作符來創建它的一個實例。
const HtmlWebpackPlugin = require(‘html-webpack-plugin‘); // 通過 npm 安裝
const webpack = require(‘webpack‘); // 用於訪問內置插件
const config = {
module: {
rules: [
{ test: /\.txt$/, use: ‘raw-loader‘ }
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin(),
new HtmlWebpackPlugin({template: ‘./src/index.html‘})
]
};
module.exports = config;
webpack 提供許多開箱可用的插件!查閱插件列表獲取更多信息。
在 webpack 配置中使用插件是簡單直接的,然而也有很多值得我們進一步探討的用例。
了解更多
webpack-dev-server
本地服務器
安裝
npm install webpack-dev-server -S
基本概念
可以構建一個本地服務器進行啟動測試
配置webpack.config.js
webpack.config.js
devServer: {
contentBase: path.join(__dirname, "/dist"), //啟動路徑
port: 9001, // 端口號
hot: true, // 熱更新
inline:true // 內聯模式
}
當然在使用上面 hot
熱更新時需要開啟一個插件 HotModuleReplacementPlugin
此插件屬於內置插件,可以直接使用 new webpack.HotModuleReplacementPlugin()
來進行啟用
以上使 webpack-dev-server
的基本參數用法,具體的可以查看此處
配置package.json
"scripts": {
"start": "webpack-dev-server --open"
}
使用 npm start
開啟啟動命令
webpack loader處理
loader : 加載程序
loader 用於對模塊的源代碼進行轉換。loader 可以使你在 import 或"加載"模塊時預處理文件。因此,loader 類似於其他構建工具中“任務(task)”,並提供了處理前端構建步驟的強大方法。loader 可以將文件從不同的語言(如 TypeScript)轉換為 JavaScript,或將內聯圖像轉換為 data URL。loader 甚至允許你直接在 JavaScript 模塊中 import CSS文件!
安裝
cnpm install css-loader style-loader -S
配置
當新建文件 *.css
文件時進行css文件處理
webpack.config.js
module:{
rules:[
{
test:/\.css$/,
use:[‘style-loader‘,‘css-loader‘]
}
]
}
在其中需要註意的就是 style-loader
在 css-loader
之前。
當 css 有 background-image: url(‘./1.jpg‘)
有圖片插入進來時,需要使用 file-loader
來進行處理
module:{
rules:[
{
test:/\.css$/,
use:[‘style-loader‘,‘css-loader‘]
},
{
test:/\.(jpg|png|jpeg)$/,
use:[‘file-loader‘]
}
]
}
設置圖片保存地方及是否使用base64進行處理
{
test:/\.(jpg|png|jpeg)$/,
use:‘file-loader?limit=1024&name=./images/[hash:8].[name].[ext]‘
}
HTML的img標記處理
安裝
cnpm install html-withimg-loader -S
配置
{
test:/\.html$/,
use:["html-withimg-loader"]
}
CSS 打包分離
安裝
cnpm install extract-text-webpack-plugin@next -S
配置
const ExtractTextPlugin=require(‘extract-text-webpack-plugin‘);
//插件
new ExtractTextPlugin(‘./css/[name].css‘)
// rules
{
test:/\.css$/,
use:ExtractTextPlugin.extract({
fallback:"style-loader",
use:[{
loader:"css-loader",
options:{
// 壓縮
minimize:true
}
}],
// 添加公共路徑
publicPath:"../"
})
}
webpack 插件
插件是 webpack 的支柱功能。webpack 自身也是構建於,你在 webpack 配置中用到的相同的插件系統之上!
插件目的在於解決 loader 無法實現的其他事。
剖析
webpack 插件是一個具有 apply 屬性的 JavaScript 對象。apply 屬性會被 webpack compiler 調用,並且 compiler 對象可在整個編譯生命周期訪問。
ConsoleLogOnBuildWebpackPlugin.js
const pluginName = ‘ConsoleLogOnBuildWebpackPlugin‘;
class ConsoleLogOnBuildWebpackPlugin {
apply(compiler) {
compiler.hooks.run.tap(pluginName, compilation => {
console.log("webpack 構建過程開始!");
});
}
}
compiler hook 的 tap 方法的第一個參數,應該是駝峰式命名的插件名稱。建議為此使用一個常量,以便它可以在所有 hook 中復用。
用法
由於插件可以攜帶參數/選項,你必須在 webpack 配置中,向 plugins
屬性傳入 new
實例。
根據你的 webpack 用法,這裏有多種方式使用插件。
配置
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;
當然上面的 HtmlWebpackPlugin
插件只使用了基本的功能,更多的參數可以去github上查看。
webpack babel
安裝
核心
babel-core
功能
babel-loader
babel-preset-env
babel-preset-react
babel-loader 7.x 版本安裝
cnpm install babel-core babel-loader@7 babel-preset-env babel-preset-react --save
安裝的 babel-loader
是7.x版本,8.x版本目前會出現報錯,具體如何解決還沒有了解清楚,所以安裝 babel-loader
時需要寫成這樣的 babel-loader@7
babel-loader 8.x 版本安裝
cnpm install -D babel-loader @babel/core @babel/preset-env @babel/preset-react -S
上面為 babel-loader 8.x
版本安裝,需要匹配下面的 8.x 配置
配置
babel-loader 7.x 版本配置
第一種 全在 webpack.config.js
中配置
rules:[
{
test:/\.(jsx|js)$/,
use:{
loader:‘babel-loader‘,
options:{
presets:[‘env‘,‘react‘]
}
},
// 排除node_modules 文件
exclude:/node_modules/
}
]
第二種 新建 .babelrc
文件 (推薦使用第二種)
webpack.config.js
rules:[
{
test:/\.(jsx|js)$/,
use:{
loader:‘babel-loader‘
},
// 排除node_,modules 文件
exclude:/node_modules/
}
]
.baelrc
{
"presets": [
"env",
"react"
]
}
babel-loader 8.x 版本配置
第一種 全在 webpack.config.js
中配置
rules:[
{
test:/\.(jsx|js)$/,
use:{
loader:‘babel-loader‘,
options:{
presets:[‘"@babel/preset-env‘,‘"@babel/preset-react‘]
}
},
// 排除node_modules 文件
exclude:/node_modules/
}
]
第二種 新建 .babelrc
文件 (推薦使用第二種)
webpack.config.js
rules:[
{
test:/\.(jsx|js)$/,
use:{
loader:‘babel-loader‘
},
// 排除node_,modules 文件
exclude:/node_modules/
}
]
.baelrc
{
"presets": [
""@babel/preset-env",
""@babel/preset-react"
]
}
webpack 引入第三方庫
安裝
cnpm install jquery -S
使用
在webpack 3.x 中需要大量配置,但是在webpack中則少了很多
const $ = require("jquery");
$("body").html("<p>我是由JQuery寫出來的</p>")
webpack 4.x 初級學習記錄