目錄
解決webpack-cli和webpack-dev-server版本衝突問題
通過html-webpack-plugin外掛生成html(自動引入js程式碼)
一個前端資源載入/打包工具。它將根據模組的依賴關係進行靜態分析,然後將這些模組按照指定的規則生成對應的靜態資源(把一堆的css檔案和js檔案放在一個總的入口檔案,通過require引入,剩下的事情webpack會處理,包括所有模組的前後依賴關係,打包、壓縮、合併成一個js檔案,公共程式碼抽離成一個js檔案、某些自己指定的js單獨打包,模組可以是css/js/imsge/font等等)。
下面是webpack包含的一些模組。
首先使用命令列全域性安裝webpack、webpack-cli、webpack-dev-server,其中webpack-cli需要指定版本號,因為預設安裝的最新是4點幾的版本和webpack-dev-server最新3點幾的版本衝突。以下命令列程式碼都是在當前資料夾下執行,-D表示下載為本地專案依賴和-save-dev相同,然後npm install和yarn add相同都是下載檔案
命令列:npm install webpack webpack-cli@3.3.12 webpack-dev-server -g安裝全域性webpack命令。
已安裝了最新版本的可以通過下面方法解決。
將webpack.config.js中"start"修改如下:
"scripts": {
"build": "node_modules/.bin/webpack --config webpack.config.js",
"start": "webpack serve --config webpack.config.js --open "
}
在專案資料夾(取名不要為webpack)下建立src、dist、config資料夾,然後通過npm init -y建立package.js檔案。然後在dist資料夾下建立index.html(主網頁程式碼),在src資料夾下建立index.js檔案,再次安裝npm install webpack webpack-cli@3.3.12 webpack-dev-server -D(因為組態檔需要使用到require等語句匯入webpack中的模組)。
webpack4點幾提供的新打包命令,當需要載入css、圖片(載入外掛和使用loaders等)等時還是需要使用webpack.dev.js打包。
在命令列中輸入webpack --mode=development (打包模式為開發者環境)或webpack --mode=production(打包模式為生產者環境,經過壓縮了,不會打包一些未使用的程式碼),最後在dist的資料夾下會生成main.js檔案。
緊接構建基本框架後,並在src資料夾下建立main.js,在config檔案下建立webpack.dev.js。編輯webpack.dev.js檔案如下圖,引數含義如下:
其中entry為入口通過陣列包裹多個入口檔名(此時會將陣列中的多個檔案打包成一個檔案,要想打包成輸出多個檔案,可給entry物件新增屬性index:['./src/main.js'],這時便會多生成一個打包檔案index-bundle.js),mode為模式可以為development和production,output為出口只能有一個出口,filename代表出口檔名[name]代表入口檔案的main,生成的檔名為main-bundle.js(該檔案包含所有js檔案,在index.html中便只需要匯入該檔案),path為路徑path.resolve()會返回路徑名(將引數進行拼接後的路徑名,若字元以 / 開頭,不會拼接到前面的路徑;若以 ../ 開頭,拼接前面一個引數的路徑,該引數不含最後一節路徑;若以 ./ 開頭或者沒有符號 則拼接前面路徑),__dirname代表當前檔案的絕對路徑(不包含檔名),程式碼中的意思是返回dist檔案的絕對路徑。publicPath為設定當前的路徑名,例如'/'時,在index.html中引入main-bundle.js就需要通過'/main-bundle.js'或'main-bundle.js';而為'/js'時,就需要通過'/js/main-bundle.js'引入。devServer代表本地伺服器,contentBase代表設定http://localhost:8080/存取的基礎路勁為dist檔案即直接存取indexl.html(未設定的話http://localhost:8080/會開啟專案的目錄),overlay讓錯誤資訊可以在網頁中顯示,port代表原生的埠預設為8080,open為是否自動開啟網頁。
const path = require('path')
module.exports = {
entry: {
main: ['./src/main.js','./src/index.js']
},
mode: 'development',
output: {
filename: '[name]-bundle.js',
path: path.resolve(__dirname, '../dist'),
publicPath:'/'
},
devServer:{
contentBase: 'dist',
overlay: true,
port:8080,
open:true
},
// module:{
// rules:[
// {
// test:/\.css$/,
// use:[
// {
// loader:'style-loader'
// },
// {
// loader:'css-loader'
// }
// ]
// }
// ]
// }
}
命令列中執行webpack --config=config/webpack.dev.js(按照webpack.dev.js中的設定打包檔案)然後會在dist資料夾下生成main-bundle.js,最後輸入webpack-dev-server --config=config/webpack.dev.js(按照webpack.dev.js中的設定把專案佈置到本地伺服器上,可以不用生成main-bundle.js即可以在上一個命令前執行),便可以在網頁上開啟http://localhost:8080/存取到index.html檔案,而index.html檔案便可以通過引入main-bundle.js引入index.js和main.js。
修改package.json中的script標籤,如下圖新增start和build。這時npm start命令便等於webpack-dev-server --config=config/webpack.dev.js。
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start":"webpack-dev-server --config=config/webpack.dev.js",
"build":"webpack --config=config/webpack.dev.js"
}
在命令列輸入npm install jquery -D,然後在main.js中通過const $=require('jquery'),之後再main.js中便可以通過$符號來使用jQery函數。
將index.html移入src資料夾下,執行命令列npm install html-webpack-plugin -D安裝外掛,設定webpack.dev.js中寫入const HtmlWebpackPlugin = require('html-webpack-plugin')用於引入自動生成html的外掛,給module.export指向的物件新增屬性plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })],其中template指定的模板便是移入src資料夾下的index.html的路徑,這裡需要注意雖然我的webpack.dev.js檔案是在config資料夾下,但是這裡的相對路勁./依然指的是專案路徑即config的上層路徑。最後執行webpack --config=config/webpack.dev.js後會在dist檔案上生成一個index.js檔案,該檔案中會自動引入main-bundle.js即打包後的出口檔案(不需要手動引入了)。
在src資料夾下建立main.css在main.js中通過require('./main.css')引入,命令列輸入npm install style-loader css-loader -D安裝css-loader(能識別CSS並載入,支援模組化、壓縮、檔案匯入等特性)和style-loader(通過動態建立style標籤的方式,讓解析後的css內容能夠作用到頁面中)。然後將webpack.dev.js圖中註釋內容開啟即可(test是通過正規表示式匹配檔案,use中為使用的loader),再次執行webpack-dev-server --config=config/webpack.dev.js便可以在http://localhost:8080/中看到新增了css的index.html檔案。在devServer中新增屬性overlay:true可以使錯誤資訊不僅在命令列中顯示,還會在頁面中顯示。
命令列輸入npm install mini-css-extract-plugin -D安裝分離外掛,在webpack.dev.js中輸入const MiniCssExtractPlugin = require('mini-css-extract-plugin'),將之前設定style-loader的物件替換為{loader:MiniCssExtractPlugin.loader},最後在plugins的陣列中新增new MiniCssExtractPlugin({filename:'./index.css'})即可,filename代表分離出來的css名字和地址,這裡注意./表示的位置是dist資料夾下。
less是css預處理檔案,引入了變數函數等是css處理更靈活。首先命令列輸入npm install less less-loader -D,然後在src資料夾下建立iheader.less檔案,在main.js中寫入require('./header.less'),然後設定ebpack.dev.js,在rules陣列中新增{test: /\.less$/i,use: ["style-loader","css-loader","less-loader",],},注意這裡還是會生成style標籤插入,想要分離出來,把"style-loader"替換為{loader:MiniCssExtractPlugin.loader},這時less檔案也會被分離到index.css中。
命令列輸入npm install url-loader file-loader -D,設定webpack.dev.js檔案,在rules陣列中新增物件{test: /\.(png|jpg|gif)$/i,use: [{loader: 'url-loader',options: {limit: 8192,name:'[name].[ext]',publicPath:'images/',outputPath:'images/'}}]}即可,這時可以在css和less檔案中使用圖片,(這裡的圖片會被預設轉換為base64字串格式,好處是瀏覽器不用傳送請求了,直接可以讀取,壞處是圖片如果太大,會導致轉換後體積增大30%,所以這裡設定了大小限制limit,表示當大於8kb時,在dist資料夾中建立images資料夾,在該資料夾下生成圖片,通過連結匯入,小於時才會base64轉換),注意css和less檔案中使用圖片的地址是src下的圖片和檔案的相對地址,而html中img標籤使用的地址是publicPath(靜態資源的參照路徑)。
命令列輸入npm install clean-webpack-plugin -D,在webpack.dev.js中輸入const { CleanWebpackPlugin } = require('clean-webpack-plugin'),然後在plugins陣列中新增new CleanWebpackPlugin()即可,這時我們每次輸入命令列webpack --config=config/webpack.dev.js後都會先清空dist資料夾,然後在生成打包的檔案。
命令列輸入npm install -D babel-loader @babel/core @babel/preset-env,在webpack.dev.js中rules陣列下新增物件{test: /\.m?js$/,exclude: /(node_modules|bower_components)/,use:{ loader: 'babel-loader',options: {presets: ['@babel/preset-env']}}},此時如果在main.js寫了es6的語法會被轉換成es5(在最後的輸出檔案main-bundle.js可以檢視)。
命令列輸入npm install webpack-merge -D,在config資料夾下新建檔案webpack.pro.js(生產環境設定)和webpack.base.js(公用設定),之前的webpack.dev.js是開發環境的設定。設定webpack.base.js,將之前webpack.dev.js的內容全部複製過去,去除devServer和mode屬性,然後在重新設定webpack.dev.js為下圖程式碼,接著設定webpack.pro.js同樣為下圖,不同在於去除devServer屬性並將mode改為'production'即可(下圖中引數其中meige()中可以傳入多個物件,會將多個引數合併成一個物件,如果有重複屬性名,後面的物件屬性會覆蓋前面的)。
const base = require('./webpack.base');
const {merge} = require('webpack-merge');
module.exports = merge(base, {
mode: 'development',
devServer: {
contentBase: 'dist',
overlay: true,
port: 8080,
open: true
}
})
此時可以通過webpack --config=config/webpack.dev.js打包為開發環境的,通過webpack --config=config/webpack.pro.js打包為生產者環境。
當有多入口檔案生成多個打包檔案時,如果入口檔案中都用到jQuery,需要都引入,這時打包檔案會重複打包jquery,需要重新設定在webpack.base的module.exports物件中新增屬性optimization: {splitChunks: {chunks: 'all'}},這時便會提取公共模組設定。不會重複打包重複的模組。
需要config檔案,src檔案,pack.json檔案,然後進入到專案檔案中命令列輸入yarn即可安裝他人所有區域性依賴,這樣便可以通過之前命令打包和佈置本地伺服器上使用。
https://v4.webpack.js.org/plugins/
https://v4.webpack.js.org/loaders/