遇見的問題TypeError: Cannot read property ‘tap’ of undefined
先看專案目錄結構 :關于專案的修改及改造 再專案完事的時候會發布的



如果你也遇見這個問題的話 這一篇博客應該完全可以解決
問題描述:
building for sit environment...D:\EVDownload\adminMPA\node_modules\script-ext-html-webpack-plugin\lib\plugin.js:50
compilation.hooks.htmlWebpackPluginAlterAssetTags.tap(PLUGIN, alterAssetTags);
^
TypeError: Cannot read property 'tap' of undefined
at ScriptExtHtmlWebpackPlugin.compilationCallback (D:\EVDownload\adminMPA\node_modules\script-ext-html-webpack-plugin\lib\plugin.js:50:57)
at SyncHook.eval [as call] (eval at create (D:\EVDownload\adminMPA\node_modules\tapable\lib\HookCodeFactory.js:19:10), <anonymous>:11:1)
at SyncHook.lazyCompileHook (D:\EVDownload\adminMPA\node_modules\tapable\lib\Hook.js:154:20)
at Compiler.newCompilation (D:\EVDownload\adminMPA\node_modules\webpack\lib\Compiler.js:504:26)
at D:\EVDownload\adminMPA\node_modules\webpack\lib\Compiler.js:540:29
at AsyncSeriesHook.eval [as callAsync] (eval at create (D:\EVDownload\adminMPA\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:6:1)
at AsyncSeriesHook.lazyCompileHook (D:\EVDownload\adminMPA\node_modules\tapable\lib\Hook.js:154:20)
at Compiler.compile (D:\EVDownload\adminMPA\node_modules\webpack\lib\Compiler.js:535:28)
at D:\EVDownload\adminMPA\node_modules\webpack\lib\Compiler.js:274:11
at Compiler.readRecords (D:\EVDownload\adminMPA\node_modules\webpack\lib\Compiler.js:402:11)
at D:\EVDownload\adminMPA\node_modules\webpack\lib\Compiler.js:271:10
at AsyncSeriesHook.eval [as callAsync] (eval at create (D:\EVDownload\adminMPA\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:6:1)
at AsyncSeriesHook.lazyCompileHook (D:\EVDownload\adminMPA\node_modules\tapable\lib\Hook.js:154:20)
at D:\EVDownload\adminMPA\node_modules\webpack\lib\Compiler.js:268:19
at AsyncSeriesHook.eval [as callAsync] (eval at create (D:\EVDownload\adminMPA\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:15:1)
at AsyncSeriesHook.lazyCompileHook (D:\EVDownload\adminMPA\node_modules\tapable\lib\Hook.js:154:20)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! admin@1.0.0 build:sit: `cross-env NODE_ENV=production env_config=sit node build/build.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the admin@1.0.0 build:sit script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\l\AppData\Roaming\npm-cache\_logs\2020-11-10T02_45_03_911Z-debug.log
這個問題全網只有兩個人寫過博客 但是不適合我這個 (我也不知道為啥 )
如果你也有這樣的問題可以嘗試下:
第一篇博客解決辦法發是 webpack 和 webpackServe 及 html-webpack-plugin 版本沖突 這個直接去重寫install 個版本就好了
博客鏈接 : https://blog.csdn.net/qq_31290307/article/details/86158770
第二篇博客解決辦法如下 :
set “html-webpack-plugin”: “^4.0.0-alpha” => “4.0.0-alpha”
remove node_modules
remove package-lock.json
npm install
博客鏈接: https://www.cnblogs.com/ybz94/p/9625864.html
以上兩篇博客如果還不能解決你的問題 那你就跟著我走吧! 以下是我的解決思路
第一點 : 檢查入口檔案 是不是有多余的東西
列印結果如下 :

對比圖 
在這里我們發現入口檔案 多了幾個js 分別是 errorLog.js 和 permission.js
所以我們要做的操作是 將多余的js洗掉
入口函式寫法如下
//多入口配置
// 通過glob模塊讀取views檔案夾下的所有對應檔案夾下的js后綴檔案,如果該檔案存在
// 那么就作為入口處理
exports.entries = function() {
var entryFiles = glob.sync(PAGE_PATH + '/*/*.js')
// console.log(entryFiles ,'entryCha')
var map = {}
entryFiles.forEach((filePath) => {
var filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'))
map[filename] = filePath
})
delete map.errorLog ;
delete map.permission ;
console.log(map ,'map')
return map
}
修改完入口檔案后 我再次打包發現問題依舊 , 別灰心繼續搞 , webpack 打包主要就是入口和出口 接下來我們研究下出口檔案函式 我一開始寫法如下 :
//多頁面輸出配置
// 與上面的多頁面入口配置相同,讀取pages檔案夾下的對應的html后綴檔案,然后放入陣列中
exports.htmlPlugin = function() {
// let entryHtml = path.resolve(__dirname + '../dist/*.html')
let entryHtml = glob.sync(PAGE_PATH + '/*/*.html')
let arr = []
entryHtml.forEach((filePath) => {
let filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'))
let conf = {
// 模板來源
template: filePath,
// 檔案名稱
filename: filename + '.html',
// 頁面模板需要加對應的js腳本,如果不加這行則每個頁面都會引入所有的js腳本
chunks: ['manifest', 'vendor', filename],
inject: true,
templateParameters: {
BASE_URL: config.build.assetsPublicPath + config.build.assetsSubDirectory,
},
}
if (process.env.NODE_ENV === 'production') {
conf = merge(conf, {
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
},
chunksSortMode: 'dependency'
})
}
arr.push(new HtmlWebpackPlugin(conf))
})
console.log(arr , 'arr')
return arr
}
我們看下列印的資料對不對
[
HtmlWebpackPlugin {
options: {
template: 'D:/EVDownload/adminMPA/src/views/index/index.html',
templateContent: false,
templateParameters: [Object],
filename: 'index.html',
hash: false,
inject: true,
compile: true,
favicon: false,
minify: false,
cache: true,
showErrors: true,
chunks: [Array],
excludeChunks: [],
chunksSortMode: 'auto',
meta: {},
title: 'Webpack App',
xhtml: false
},
childCompilerHash: undefined,
childCompilationOutputName: undefined,
assetJson: undefined,
hash: undefined,
version: 4
},
HtmlWebpackPlugin {
options: {
template: 'D:/EVDownload/adminMPA/src/views/page/page.html',
templateContent: false,
templateParameters: [Object],
filename: 'page.html',
hash: false,
inject: true,
compile: true,
favicon: false,
minify: false,
cache: true,
showErrors: true,
chunks: [Array],
excludeChunks: [],
chunksSortMode: 'auto',
meta: {},
title: 'Webpack App',
xhtml: false
},
childCompilerHash: undefined,
childCompilationOutputName: undefined,
assetJson: undefined,
hash: undefined,
version: 4
},
HtmlWebpackPlugin {
options: {
template: 'D:/EVDownload/adminMPA/src/views/pagetwo/pagetwo.html',
templateContent: false,
templateParameters: [Object],
filename: 'pagetwo.html',
hash: false,
inject: true,
compile: true,
favicon: false,
minify: false,
cache: true,
showErrors: true,
chunks: [Array],
excludeChunks: [],
chunksSortMode: 'auto',
meta: {},
title: 'Webpack App',
xhtml: false
},
childCompilerHash: undefined,
childCompilationOutputName: undefined,
assetJson: undefined,
hash: undefined,
version: 4
}
]
仔細瞅了一下 , 也沒有大問題 ,但是當我打開config檔案時 發現我在這里竟然也設定了build路徑 【奔潰】,那么再重新修改下打包路徑吧 ,
第一步在 webpack.dev.conf.js 里修改
plugins: [
new webpack.DefinePlugin({
'process.env': require('../config/dev.env')
}),
new webpack.HotModuleReplacementPlugin(),
/* 在這開始插入代碼*********************************************************/
new htmlWebpackPlugin({
filename : 'index.html',//輸出的html路徑
template : 'index.html', //html模板路徑
//inject : 'head', //js檔案在head中,若為body則在body中
inject : true,
title : 'index',
chunks : ['app'], //打包時只打包main和a的js檔案,見entry,注意使用chunks時模板index.html檔案里面不允許有script標簽,即使注釋掉也會報錯
templateParameters: {
BASE_URL: config.dev.assetsPublicPath + config.dev.assetsSubDirectory
}
}),
new htmlWebpackPlugin({
filename : 'page.html',//輸出的html路徑
template : 'page.html', //html模板路徑
//inject : 'head', //js檔案在head中,若為body則在body中
inject : true,
title : 'page',
chunks : ['page'], //打包時只打包main和a的js檔案,見entry,注意使用chunks時模板index.html檔案里面不允許有script標簽,即使注釋掉也會報錯
templateParameters: {
BASE_URL: config.dev.assetsPublicPath + config.dev.assetsSubDirectory
}
}),
new htmlWebpackPlugin({
filename : 'pagetwo.html',//輸出的html路徑
template : 'pagetwo.html', //html模板路徑
//inject : 'head', //js檔案在head中,若為body則在body中
inject : true,
title : 'pagetwo',
chunks : ['pagetwo'], //打包時只打包main和a的js檔案,見entry,注意使用chunks時模板index.html檔案里面不允許有script標簽,即使注釋掉也會報錯
templateParameters: {
BASE_URL: config.dev.assetsPublicPath + config.dev.assetsSubDirectory
}
}),
/* 在這結束插入代碼*********************************************************/
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
new webpack.NoEmitOnErrorsPlugin(),
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.dev.assetsSubDirectory,
ignore: ['.*']
}
])
]
})
因為我這有三個動態專案 目前插如三個 new htmlWebpackPlugin
在webpack.prod.conf.js 里修改如下
plugins: [
// http://vuejs.github.io/vue-loader/en/workflow/production.html
new webpack.DefinePlugin({
'process.env': env
}),
// extract css into its own file
new MiniCssExtractPlugin({
filename: utils.assetsPath('css/[name].[contenthash:8].css'),
chunkFilename: utils.assetsPath('css/[name].[contenthash:8].css')
}),
/* 開始插入代碼 ************************************************/
new HtmlWebpackPlugin({
filename: config.build.app,
template: 'index.html',
inject: true,
favicon: resolve('favicon.ico'),
title: 'index',
templateParameters: {
BASE_URL: config.build.assetsPublicPath + config.build.assetsSubDirectory
},
chunks: ['manifest', 'vendor', 'app'],
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
}
// default sort mode uses toposort which cannot handle cyclic deps
// in certain cases, and in webpack 4, chunk order in HTML doesn't
// matter anyway
}),
new HtmlWebpackPlugin({
filename: config.build.page,
template: 'page.html',
inject: true,
favicon: resolve('favicon.ico'),
title: 'page',
templateParameters: {
BASE_URL: config.build.assetsPublicPath + config.build.assetsSubDirectory
},
chunks: ['manifest', 'vendor', 'page'],
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
}
// default sort mode uses toposort which cannot handle cyclic deps
// in certain cases, and in webpack 4, chunk order in HTML doesn't
// matter anyway
}),
new HtmlWebpackPlugin({
filename: config.build.pagetwo,
template: 'pagetwo.html',
inject: true,
favicon: resolve('favicon.ico'),
title: 'pagetwo',
templateParameters: {
BASE_URL: config.build.assetsPublicPath + config.build.assetsSubDirectory
},
chunks: ['manifest', 'vendor', 'pagetwo'],
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
}
// default sort mode uses toposort which cannot handle cyclic deps
// in certain cases, and in webpack 4, chunk order in HTML doesn't
// matter anyway
}),
/* 結束插入代碼 ************************************************/
new ScriptExtHtmlWebpackPlugin({
//`runtime` must same as runtimeChunk name. default is `runtime`
inline: /runtime\..*\.js$/
}),
// keep chunk.id stable when chunk has no name
new webpack.NamedChunksPlugin(chunk => {
if (chunk.name) {
return chunk.name
}
const modules = Array.from(chunk.modulesIterable)
if (modules.length > 1) {
const hash = require('hash-sum')
const joinedHash = hash(modules.map(m => m.id).join('_'))
let len = nameLength
while (seen.has(joinedHash.substr(0, len))) len++
seen.add(joinedHash.substr(0, len))
return `chunk-${joinedHash.substr(0, len)}`
} else {
return modules[0].id
}
}),
// keep module.id stable when vender modules does not change
new webpack.HashedModuleIdsPlugin(),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.build.assetsSubDirectory,
ignore: ['.*']
}
])
] ,
在這里也插入代碼 (注釋里有標記哦!!!!!!!!!!!)
好了 現在在運行下吧 看看效果咋樣呢?

打包完成 成功啦 !
小記
這個bug 說白了 問題的根點在出口檔案這 , 為什么會在這呢 ? 相關檔案有說 是因為 webpack 新增 hook 屬性 造成的看的我迷迷糊糊的 沒明白 大致就是說你的出口檔案應該怎么設定啥的, 哎!腦殼疼
為什么出口檔案不能放在公共的utils 里呢 ? 目前這樣打包問題雖然解決但是 每次的修改過于復雜 (腦殼疼), 如果有大神的話感謝指導下哈!!!后期我會把這個專案開源 詳細請到個人中心查看
再此特別鳴謝 @璠哥 (一個溫文爾雅的漂亮妹子) @勁琪 (一個陽光帥氣的小帥哥)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/211675.html
標籤:python
上一篇:原生JS實作彈幕的簡單操作速成
