Files
fitness_walk_nwnu/node_modules/@dcloudio/vue-cli-plugin-uni/lib/configure-webpack.js
T
2026-09-08 20:28:54 +08:00

411 lines
14 KiB
JavaScript

const path = require('path')
const webpack = require('webpack')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const CopyWebpackPluginVersion = Number(require('copy-webpack-plugin/package.json').version.split('.')[0])
const merge = require('webpack-merge')
const {
getPartialIdentifier
} = require('./util')
function resolve (dir) {
return path.resolve(__dirname, '..', dir)
}
module.exports = function configureWebpack (platformOptions, manifestPlatformOptions, vueOptions, api) {
const {
runByHBuilderX, // 使用 HBuilderX 运行
isInHBuilderX, // 在 HBuilderX 的插件中
hasModule,
jsPreprocessOptions,
htmlPreprocessOptions,
uts
} = require('@dcloudio/uni-cli-shared')
const {
getPlatformVue
} = require('@dcloudio/uni-cli-shared/lib/platform')
const {
getCopyWebpackPluginOptions
} = require('./copy-webpack-options')
function createMatcher (fakeFile) {
return (rule, i) => {
const clone = Object.assign({}, rule)
delete clone.include
if (webpack.version[0] > 4) {
const BasicEffectRulePlugin = require('webpack/lib/rules/BasicEffectRulePlugin')
const BasicMatcherRulePlugin = require('webpack/lib/rules/BasicMatcherRulePlugin')
const RuleSetCompiler = require('webpack/lib/rules/RuleSetCompiler')
const UseEffectRulePlugin = require('webpack/lib/rules/UseEffectRulePlugin')
const ruleSetCompiler = new RuleSetCompiler([
new BasicMatcherRulePlugin('test', 'resource'),
new BasicMatcherRulePlugin('include', 'resource'),
new BasicMatcherRulePlugin('exclude', 'resource', true),
new BasicMatcherRulePlugin('resource'),
new BasicMatcherRulePlugin('conditions'),
new BasicMatcherRulePlugin('resourceQuery'),
new BasicMatcherRulePlugin('realResource'),
new BasicMatcherRulePlugin('issuer'),
new BasicMatcherRulePlugin('compiler'),
new BasicEffectRulePlugin('type'),
new BasicEffectRulePlugin('sideEffects'),
new BasicEffectRulePlugin('parser'),
new BasicEffectRulePlugin('resolve'),
new BasicEffectRulePlugin('generator'),
new UseEffectRulePlugin()
])
const ruleSet = ruleSetCompiler.compile([{
rules: [clone]
}])
const rules = ruleSet.exec({
resource: fakeFile
})
return rules.length > 0 && rule.use
} else {
const RuleSet = require('webpack/lib/RuleSet')
const normalized = RuleSet.normalizeRule(clone, {}, '')
return (
!rule.enforce &&
normalized.resource &&
normalized.resource(fakeFile)
)
}
}
}
function updateJsLoader (rawRules, fakeFile, checkLoaderRegex, loader) {
const matchRule = rawRules.find(createMatcher(fakeFile))
const matchUse = matchRule.use
const matchLoaderUseIndex = matchUse.findIndex(u => {
return checkLoaderRegex.test(u.loader)
})
if (matchLoaderUseIndex < 0) {
throw new Error(`No matching use for ${fakeFile}`)
}
matchUse.push(loader)
}
const tsLoaderOptions = require('./util').getTsLoadOptions()
function updateTsLoader (rawRules, fakeFile, loader, appendUTS = false) {
const matchRule = rawRules.find(createMatcher(fakeFile))
if (matchRule && matchRule.use) {
if (isInHBuilderX) {
matchRule.use.forEach(matchUse => {
if (matchUse.loader.includes('ts-loader')) {
Object.assign(matchUse.options, tsLoaderOptions)
if (appendUTS) {
if (!Array.isArray(matchUse.options.appendTsSuffixTo)) {
matchUse.options.appendTsSuffixTo = [matchUse.options.appendTsSuffixTo]
}
matchUse.options.appendTsSuffixTo.push(/\.uts$/)
}
}
})
}
if (appendUTS) {
if (!Array.isArray(matchRule.test)) {
matchRule.test = [matchRule.test]
}
matchRule.test.push(/\.uts$/)
}
matchRule.use.push(loader)
}
}
function removeForkTsCheckerWebpackPlugin (rawPlugins) {
if (isInHBuilderX && hasModule('fork-ts-checker-webpack-plugin')) {
const pluginIndex = rawPlugins.findIndex(rawPlugin => rawPlugin.vue && rawPlugin.typescriptVersion)
if (pluginIndex !== -1) {
// 移除fork-ts-checker-webpack-plugin
rawPlugins.splice(pluginIndex, 1)
// 恢复vue-loader的ts检查
tsLoaderOptions.transpileOnly = false
}
}
}
const babelLoaderRe = /^babel-loader|(\/|\\|@)babel-loader/
const cacheLoaderRe = /^cache-loader|(\/|\\|@)cache-loader/
return function (webpackConfig) {
// disable js cache-loader
const rawRules = webpackConfig.module.rules
for (let i = rawRules.length - 1; i >= 0; i--) {
const uses = rawRules[i].use
if (Array.isArray(uses)) {
const babelLoader = uses.find(use => babelLoaderRe.test(use.loader))
if (babelLoader) {
const options = api.genCacheConfig('babel-loader/' + process.env.UNI_PLATFORM, getPartialIdentifier())
if (webpack.version[0] > 4) {
babelLoader.options = babelLoader.options || {}
Object.assign(babelLoader.options, process.env.UNI_USING_CACHE ? options : {
cacheDirectory: false
})
} else {
const index = uses.findIndex(use => cacheLoaderRe.test(use.loader))
if (index >= 0) {
if (process.env.UNI_USING_CACHE) {
Object.assign(uses[index].options, options)
} else {
uses.splice(index, 1)
}
}
}
}
}
}
// 如果在 HBuilderX 中
removeForkTsCheckerWebpackPlugin(webpackConfig.plugins)
// js preprocess
updateJsLoader(rawRules, 'foo.js', babelLoaderRe, {
loader: resolve('packages/webpack-preprocess-loader'),
options: jsPreprocessOptions
})
// ts options and preprocess
updateTsLoader(rawRules, 'foo.ts', {
loader: resolve('packages/webpack-preprocess-loader'),
options: jsPreprocessOptions
}, true)
updateTsLoader(rawRules, 'foo.tsx', {
loader: resolve('packages/webpack-preprocess-loader'),
options: jsPreprocessOptions
})
let platformWebpackConfig = platformOptions.webpackConfig
if (typeof platformWebpackConfig === 'function') {
platformWebpackConfig = platformWebpackConfig(webpackConfig, vueOptions, api)
}
// 移除 node_modules 目录,避免受路径上的 node_modules 影响
if (require('@dcloudio/uni-cli-shared/lib/util').isInHBuilderX) {
webpackConfig.resolve.modules = webpackConfig.resolve.modules.filter(module => module !== 'node_modules')
}
const plugins = []
const isAppView = process.env.UNI_PLATFORM === 'app-plus' &&
vueOptions.pluginOptions &&
vueOptions.pluginOptions['uni-app-plus'] &&
vueOptions.pluginOptions['uni-app-plus'].view
if (!isAppView) { // app-plus view不需要copy
const patterns = getCopyWebpackPluginOptions(manifestPlatformOptions, vueOptions)
plugins.push(new CopyWebpackPlugin(CopyWebpackPluginVersion > 5 ? {
patterns
} : patterns))
const uniExtApis = require('@dcloudio/uni-cli-shared/lib/uts/uni_modules')
.parseUniExtApis(false, process.env.UNI_UTS_PLATFORM, 'javascript')
const keys = Object.keys(uniExtApis)
if (keys.length) {
const provides = {}
keys.forEach(name => {
const provide = uniExtApis[name]
if (Array.isArray(provide) && provide.length === 3) {
provide.pop()
}
provides[name] = provide
})
plugins.push(new webpack.ProvidePlugin(provides))
}
}
if (!process.env.UNI_SUBPACKGE || !process.env.UNI_MP_PLUGIN) {
try {
const automatorJson = require.resolve('@dcloudio/uni-automator/dist/automator.json')
const patterns = [{
from: automatorJson,
to: '../.automator/' + (process.env.UNI_SUB_PLATFORM || process.env.UNI_PLATFORM) +
'/.automator.json',
transform (content) {
if (process.env.UNI_AUTOMATOR_WS_ENDPOINT) {
return JSON.stringify({
version: require('@dcloudio/uni-automator/package.json').version,
wsEndpoint: process.env.UNI_AUTOMATOR_WS_ENDPOINT
})
}
return ''
}
}]
plugins.push(new CopyWebpackPlugin(CopyWebpackPluginVersion > 5 ? {
patterns
} : patterns))
} catch (e) {}
}
if (process.UNI_SCRIPT_ENV && Object.keys(process.UNI_SCRIPT_ENV).length) {
// custom define
const envs = Object.create(null)
Object.keys(process.UNI_SCRIPT_ENV).forEach(name => {
envs['process.env.' + name] = JSON.stringify(process.UNI_SCRIPT_ENV[name])
})
plugins.push(new webpack.DefinePlugin(envs))
}
if (runByHBuilderX) { // 使用 HBuilderX 中运行时,调整错误日志输出
const WebpackErrorsPlugin = require('../packages/webpack-errors-plugin')
const onErrors = require('../util/on-errors')
const onWarnings = require('../util/on-warnings')
plugins.push(new WebpackErrorsPlugin({
onErrors,
onWarnings
}))
}
const rules = [{
test: path.resolve(process.env.UNI_INPUT_DIR, 'pages.json'),
use: [{
loader: 'babel-loader'
}, {
loader: '@dcloudio/webpack-uni-pages-loader'
}],
type: 'javascript/auto'
},
{
resourceQuery: /vue&type=template/,
use: [{
loader: resolve('packages/webpack-preprocess-loader'),
options: htmlPreprocessOptions
}]
}
]
if (!process.env.UNI_USING_COMPONENTS) { // 新版本,在 script-loader 中处理(为了避免 babel generator 移除部分条件编译代码)
rules.push({
resourceQuery: /vue&type=script/,
use: [{
loader: resolve('packages/webpack-preprocess-loader'),
options: jsPreprocessOptions
}]
})
}
if (process.env.NODE_ENV === 'development' || (process.env.NODE_ENV === 'production' && process.env
.SOURCEMAP === 'true')) {
const sourceMap = require('@dcloudio/uni-cli-shared/lib/source-map')
let isAppService = false
if (
process.env.UNI_PLATFORM === 'app-plus' &&
vueOptions.pluginOptions &&
vueOptions.pluginOptions['uni-app-plus']
) {
isAppService = !!vueOptions.pluginOptions['uni-app-plus'].service
}
const useEvalSourceMap = process.env.UNI_PLATFORM === 'h5' || isAppService
const useSourceMap = process.env.UNI_PLATFORM.indexOf('mp-') === 0 &&
process.env.UNI_PLATFORM !== 'mp-baidu' &&
process.env.UNI_PLATFORM !== 'mp-alipay' &&
process.env.UNI_PLATFORM !== 'quickapp-webview' &&
process.env.UNI_PLATFORM !== 'mp-harmony' // 目前 ov 的开发工具支持 eval 模式
if (process.env.NODE_ENV === 'production') {
const sourceMapOptions = {
noSources: true,
append: false
}
if (isInHBuilderX && process.env.SOURCEMAP_PATH) {
sourceMapOptions.filename = process.env.SOURCEMAP_PATH
}
if (useEvalSourceMap || useSourceMap) {
plugins.push(sourceMap.createSourceMapDevToolPlugin(!sourceMapOptions.filename, sourceMapOptions))
}
} else {
if (useEvalSourceMap) {
plugins.push(sourceMap.createEvalSourceMapDevToolPlugin())
} else if (useSourceMap) {
plugins.push(sourceMap.createSourceMapDevToolPlugin(process.env.UNI_PLATFORM === 'mp-weixin' || process
.env.UNI_PLATFORM === 'mp-toutiao'))
}
}
}
try {
if (process.env.UNI_HBUILDERX_PLUGINS) {
require(path.resolve(process.env.UNI_HBUILDERX_PLUGINS, 'uni_helpers/lib/bytenode'))
const {
W
} = require(path.resolve(process.env.UNI_HBUILDERX_PLUGINS, 'uni_helpers'))
plugins.push(new W({
dir: process.env.UNI_INPUT_DIR
}))
}
} catch (e) {}
if (!runByHBuilderX && process.env.UNI_PLATFORM === 'mp-weixin') {
const { PreprocessorWebpackPlugin } = require('@dcloudio/uni-cli-shared/lib/preprocessor')
plugins.push(new PreprocessorWebpackPlugin())
}
const resolveLoaderAlias = {}
const modules = ['@vue/cli-plugin-babel', '@vue/cli-service']
modules.forEach(m => {
const {
dependencies
} = require(`${m}/package.json`)
Object.keys(dependencies).forEach(key => {
if (/-loader$/.test(key)) {
resolveLoaderAlias[key] = require.resolve(key)
}
})
})
const alias = {
'@': path.resolve(process.env.UNI_INPUT_DIR),
'./@': path.resolve(process.env
.UNI_INPUT_DIR), // css中的'@/static/logo.png'会被转换成'./@/static/logo.png'加载
vue$: getPlatformVue(vueOptions),
'uni-pages': path.resolve(process.env.UNI_INPUT_DIR, 'pages.json'),
'uni-stat-config': path.resolve(process.env.UNI_INPUT_DIR, 'pages.json') +
'?' +
JSON.stringify({
type: 'stat'
}),
vuex: require.resolve('@dcloudio/vue-cli-plugin-uni/packages/vuex3'),
'@vue/composition-api': require.resolve('@dcloudio/vue-cli-plugin-uni/packages/@vue/composition-api'),
'@dcloudio/uni-console': require.resolve('@dcloudio/vue-cli-plugin-uni/packages/uni-console/dist/index.esm.js')
}
if (process.env.UNI_PLATFORM.startsWith('mp')) {
const BabelRuntimeVersions = require('@babel/runtime/package.json').version.split('.')
if (BabelRuntimeVersions[0] === '7' && Number(BabelRuntimeVersions[1]) >= 18) {
alias['@babel/runtime/regenerator'] = require.resolve(
'@dcloudio/vue-cli-plugin-uni/packages/@babel/runtime/regenerator')
}
}
return merge({
devtool: false,
resolve: {
alias,
modules: [
process.env.UNI_INPUT_DIR,
path.resolve(process.env.UNI_INPUT_DIR, 'node_modules')
],
plugins: [
new uts.UTSResolverPlugin()
]
},
module: {
noParse: /^(vue|vue-router|vuex|vuex-router-sync)$/,
rules
},
resolveLoader: {
alias: resolveLoaderAlias
},
plugins,
performance: {
assetFilter (assetFilename) {
return !(/\.map$/.test(assetFilename)) && !(/vendor/.test(assetFilename))
}
},
watchOptions: require('./util').getWatchOptions()
}, platformWebpackConfig)
}
}