一次webapck4 配置文件無效的解決歷程
前言
升級webpack4,一定要去看文檔,特別是更新說明,不要自持用過原本webpack就自己開始折騰。折騰到後面,可能就默默流下眼淚了。
webpack4的變化
webpack-cli抽離
webpack-cli被單獨拆了出來,使用的時候如果只是全局裝了CLI,直接執行的時候是可以的。
webpack --config ./config/webpack.dev.js
如果是寫在npm hook裏面會發現有點問題:
//package.json "scripts": { "dev": "webpack --config ./config/webpack.dev.js" } //shall npm run dev
此時就會給提示:
One CLI for webpack must be installed. These are recommended choices, delivered as separate packages: - webpack-cli (https://github.com/webpack/webpack-cli) The original webpack full-featured CLI. - webpack-command (https://github.com/webpack-contrib/webpack-command) A lightweight, opinionated webpack CLI. We will use "npm" to install the CLI via "npm install -D". Which one do you like to install (webpack-cli/webpack-command):
如果是我沒有全局裝,我肯定會意識到要選一個,這個坑關鍵是我全局裝了。所以就在那折騰半天。
其實官方文檔開頭就說明了。
npm install webpack webpack-cli --save-dev
安裝完成之後,繼續執行發現有warning:
WARNING in configuration The ‘mode‘ option has not been set, webpack will fallback to ‘production‘ for this value. Set ‘mode‘ option to ‘development‘ or ‘production‘ to enable defaults for each environment. You can also set it to ‘none‘ to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/
mode規則
配置規則:必須在production 和 development之間選擇一種,以便webpack 使用相應模式的內置優化
- production支持所有類型的優化已生成最優bundles
- development允許註釋、提示和eval devtooldevtool的差別可以參考這裏
- production不支持watching、development針對快速增量重建進行了優化
- production支持 module concatenating(Scope Hoisting)即作用域提升,可以將模塊打包在一個函數裏,這樣減少了函數聲明,文件體積也會減小。詳細參考看這裏
- process.env.NODE_ENV被設置用來區分環境(僅僅在構建代碼而非config裏面)
- 有一個hidden none mode的模式可以禁用所有內容
用法:
配置文件中:
module.exports = { entry: Entrys, mode: ‘development‘ }
cli 參數傳入
webpack --mode=development
兩種方式都是可行的,不過我遇到過一個很坑的問題,困擾自己好幾天,最後知道真相的自己眼淚掉下來後面再提這個問題。
零配置快速開始
因為一直被吐槽配置太累,加上parcel給的壓力,webpack4也支持零配置打包了。
如果沒有配置文件,會默認以./src/index.js作為entry開始打包。
如果配置了webpack.config.js或者指定了--config 的文件路徑,則依據對應配置文件開始。
問題表現
在webpack.config.js中配置了entry、mode等相關屬性,配置文件如下:
module.export = {
mode:‘production‘,
entry:{
app:‘./src/test.js‘,
index:‘./src/test.js‘
},
output: {
path: process.cwd() + ‘/dist‘,
filename: ‘[name].[hash].js‘,
chunkFilename: ‘[name].[chunkhash].js‘,
crossOriginLoading: ‘anonymous‘
},
cache: true,
devtool: ‘cheap-source-map‘,
externals: {
jquery: ‘jQuery‘
},
module: {
rules: [
{
test: /\.(js|jsx)?$/,
include: [
path.resolve(__dirname, "../src")
],
exclude: [
‘node_modules‘,
path.resolve(__dirname, "../node_modules")
],
use: [
{
loader: ‘babel-loader‘,
options:{
presets:[‘es2015‘]
}
}
]
}
]
},
resolve: {
modules: [
‘node_modules‘
],
extensions: [".js", ".json", ".jsx", ".css"],
},
devServer: {
proxy: { // proxy URLs to backend development server
‘/api‘: ‘http://localhost:3000‘
},
contentBase: path.resolve(__dirname, "../dist"),
hot: true,
open:true
},
plugins: [
new CleanWebpackPlugin([‘dist‘]),
new HtmlWebpackPlugin({
title:‘test‘
}),
new webpack.HotModuleReplacementPlugin()
]
}
package.json命令配置:
"scripts": {
"build": "webpack --config webpack.prod.js"
}
//執行打包
npm run build
發現始終會有上面選擇mode類型的提示,這讓人不能接受,另外提示沒有./src/index.js文件,但是我的配置入口是別的文件,這樣讓人很莫名
ERROR in Entry module not found: Error: Can‘t resolve ‘./src‘ in ‘/Users/****‘
本著跟著提示解決問題的原則,少文件那就建一個唄(後來發現這種思維有時候有用,有時候還真要慎重),問題表現雖然一致,實質可能有所不同。
新建之後是可以運行了但是我們的配置文件好像沒起作用,
dist下的打包文件是默認的main.js
而非我們指定的app和index
為了確保進入配置文件,我打了幾個log,竟然都有輸出,說明進去了,這問題就詭異了。
console.log(path.resolve(__dirname, ‘./src‘)) //輸出正確路徑
module.export = {
//*****//
}
版本統一
初步猜想是版本問題,確實也有issue上提到過某些版本存在問題,對照著官方demo鎖定版本之後問題依然存在。
猜測:應該是配置文件存在錯誤
配置檢查
將官方最基本的配置拉進來拷貝進來試了一下,依然存在問題沒能解決。
猜測:本地的環境存在問題,npm,node等版本
查看之後發現版本都是滿足的。
運行demo
將demo拉到本地並啟動,demo正常打包,說明本地環境是ok的。那麽問題就明顯了,我的配置文件或者項目搭建有問題,對照著demo的配置項,配置項沒有明顯問題,這樣的話將,配置信息放入到demo中去,修改之後發現起作用,我又重新審視了下我的配置文件,不僅僅局限於配置部分的時候,發現
//我的寫法,這樣webpack拿到的就是undefined了。
module.export
//別人的demo
module.exports
webpack的兼容處理
webpack會將 webpack --config 傳入的文件與本身默認配置進行merge,保證本身打包不出錯。為了證明我們的推論,將配置文件只剩下output屬性,並加上src/index.js
module.exports = {
output: {
path: process.cwd() + ‘/dist1‘,
// 直接的入口模zzz塊名
filename: ‘[name].js‘,
// 非入口模塊,也就是不需要打包到一起的,但又可能會用到,
// 這不就是按需加載的麽
chunkFilename: ‘[name].[chunkhash].js‘,
crossOriginLoading: ‘anonymous‘
}
}
執行之後會發現打包到/dist1下面。所以上面寫錯module.exports的時候,走的完全是默認配置。前面的log打在了module.exports之前執行是正確的。
結尾
當遇到不可思議的問題的時候,建議靜下心看一看,不要盲目搜索,另外最可靠的參考就是官方文檔和實例,註意對比版本和環境,如果都沒問題,那麽再去嘗試網上的各種解決方法。
這裏總結一下給自己一個記錄,希望解決思路能幫助其他人。
一次webapck4 配置文件無效的解決歷程