Files
2026-09-08 20:28:54 +08:00

172 lines
5.6 KiB
JavaScript

const fs = require('fs')
const path = require('path')
const uniI18n = require('@dcloudio/uni-cli-i18n')
const {
log,
done
} = require('@vue/cli-shared-utils')
const {
showRunPrompt
} = require('@dcloudio/uni-cli-shared')
let nvueCompiled = true
let serviceCompiled = true
let viewCompiled = true
const nvueChangedFiles = []
const serviceChangedFiles = []
const viewChangedFiles = []
let isFirst = true
let compiling = false
class WebpackAppPlusPlugin {
apply (compiler) {
if (process.env.UNI_USING_V3) {
const chunkVersions = {}
let isAppService = false
let isAppView = false
let isAppNVue = false
const entry = compiler.options.entry()
// 兼容webpack5
if (entry instanceof Promise) {
compiler.hooks.beforeRun.tapAsync('EntryListPlugin', (compilation, callback) => {
entry.then(entry => {
isAppService = !!entry['app-service']
isAppView = !!entry['app-view']
isAppNVue = !isAppService && !isAppView
callback()
}).catch(callback)
})
} else {
isAppService = !!entry['app-service']
isAppView = !!entry['app-view']
isAppNVue = !isAppService && !isAppView
}
compiler.hooks.invalid.tap('WebpackAppPlusPlugin', (fileName, changeTime) => {
if (!compiling) {
compiling = true
console.log(uniI18n.__('performingHotReload'))
}
})
compiler.hooks.beforeCompile.tapAsync('WebpackAppPlusPlugin', (params, callback) => {
isAppNVue && (nvueCompiled = false)
isAppService && (serviceCompiled = false)
isAppView && (viewCompiled = false)
callback()
})
compiler.hooks.emit.tapAsync('WebpackAppPlusPlugin', (compilation, callback) => {
compilation.chunks.forEach(chunk => {
const oldVersion = chunkVersions[chunk.name]
chunkVersions[chunk.name] = chunk.hash
if (chunk.hash !== oldVersion && Array.isArray(chunk.files)) {
chunk.files.forEach(file => {
if (isAppService) {
!serviceChangedFiles.includes(file) && (serviceChangedFiles.push(file))
} else if (isAppView) {
!viewChangedFiles.includes(file) && (viewChangedFiles.push(file))
} else if (isAppNVue) {
!nvueChangedFiles.includes(file) && (nvueChangedFiles.push(file))
}
})
}
})
callback()
})
compiler.hooks.done.tapPromise('WebpackAppPlusPlugin', stats => {
return new Promise((resolve, reject) => {
isAppNVue && (nvueCompiled = true)
isAppService && (serviceCompiled = true)
isAppView && (viewCompiled = true)
if (serviceCompiled && viewCompiled && nvueCompiled) {
if (process.env.NODE_ENV === 'development') {
const changedFiles = [...new Set([
...serviceChangedFiles,
...viewChangedFiles,
...nvueChangedFiles
])]
let utsChangedFiles = []
try {
utsChangedFiles = JSON.parse(process.env.UNI_APP_UTS_CHANGED_FILES || '[]')
if (utsChangedFiles.length) {
changedFiles.push(...utsChangedFiles)
}
process.env.UNI_APP_UTS_CHANGED_FILES = ''
} catch (e) {}
if (!isFirst && changedFiles.length > 0) {
if (serviceChangedFiles.length === 0 && viewChangedFiles.length === 0 && utsChangedFiles
.length === 0) {
// 仅 nvue 页面发生变化
done('Build complete. PAGES:' + JSON.stringify(changedFiles))
} else {
done('Build complete. FILES:' + JSON.stringify(changedFiles))
}
} else {
// if (!stats.hasErrors()) {
!process.env.UNI_AUTOMATOR_WS_ENDPOINT && done('Build complete. Watching for changes...')
showRunPrompt()
// };
}
isFirst = false
} else {
done('Build complete. ')
showRunPrompt()
}
nvueChangedFiles.length = 0
serviceChangedFiles.length = 0
viewChangedFiles.length = 0
compiling = false
}
resolve()
})
})
} else {
compiler.hooks.done.tapPromise('WebpackAppPlusPlugin', stats => {
return new Promise((resolve, reject) => {
if (process.env.UNI_USING_NATIVE || process.env.UNI_USING_V3_NATIVE) {
return resolve()
}
const callback = function () {
fs.copyFileSync(path.resolve(process.env.UNI_OUTPUT_TMP_DIR,
'manifest.json'),
path.resolve(process.env.UNI_OUTPUT_DIR, 'manifest.json'))
log()
if (process.env.NODE_ENV === 'development') {
done('Build complete. Watching for changes...')
} else {
done('Build complete. ')
}
showRunPrompt()
resolve()
}
// Copy manifest.json
const wxmp = require(path.resolve(process.env.UNI_HBUILDERX_PLUGINS,
'weapp-tools/lib'))
try {
wxmp(
process.env.UNI_OUTPUT_TMP_DIR,
process.env.UNI_OUTPUT_DIR,
path.basename(process.env.UNI_INPUT_DIR),
callback
)
} catch (e) {
resolve()
console.error(e.message)
}
})
})
}
}
}
module.exports = WebpackAppPlusPlugin