diff --git a/packages/webpack-uni-mp-loader/lib/plugin/add-empty-component.js b/packages/webpack-uni-mp-loader/lib/plugin/add-empty-component.js new file mode 100644 index 0000000000000000000000000000000000000000..535b36037c27424d9abcb423772dd5d0ad72c182 --- /dev/null +++ b/packages/webpack-uni-mp-loader/lib/plugin/add-empty-component.js @@ -0,0 +1,38 @@ +const { createSource } = require('../shared') + +module.exports = function (compilation) { + if (process.env.UNI_PLATFORM !== 'mp-qq') { + return + } + // fix mp-qq https://github.com/dcloudio/uni-app/issues/2648 + const appJsonName = 'app.json' + const appJsonFile = compilation.getAsset(appJsonName) + if (appJsonFile) { + const componentName = 'fix-2648' + const obj = JSON.parse(appJsonFile.source.source()) + obj.usingComponents = obj.usingComponents || {} + if (!(componentName in obj.usingComponents)) { + obj.usingComponents[componentName] = `/${componentName}` + const source = JSON.stringify(obj, null, 2) + const newSource = createSource(source) + compilation.updateAsset(appJsonName, newSource) + const files = [ + { + ext: 'qml', + source: '' + }, + { + ext: 'js', + source: 'Component({})' + }, + { + ext: 'json', + source: '{"component":true}' + } + ] + files.forEach(({ ext, source }) => { + compilation.emitAsset(`${componentName}.${ext}`, createSource(source)) + }) + } + } +} diff --git a/packages/webpack-uni-mp-loader/lib/plugin/add-plugin-wrapper.js b/packages/webpack-uni-mp-loader/lib/plugin/add-plugin-wrapper.js new file mode 100644 index 0000000000000000000000000000000000000000..3b58eb1a81b29f096b360b536935cbb01eea96d1 --- /dev/null +++ b/packages/webpack-uni-mp-loader/lib/plugin/add-plugin-wrapper.js @@ -0,0 +1,38 @@ +const { createSource } = require('../shared') + +module.exports = function (compilation) { + if (process.env.UNI_PLATFORM !== 'mp-alipay') { + return + } + // fix mp-alipay plugin + const appJsonName = 'app.json' + const appJsonFile = compilation.getAsset(appJsonName) + if (appJsonFile) { + const componentName = 'plugin-wrapper' + const obj = JSON.parse(appJsonFile.source.source()) + obj.usingComponents = obj.usingComponents || {} + if (!(componentName in obj.usingComponents)) { + obj.usingComponents[componentName] = `/${componentName}` + const source = JSON.stringify(obj, null, 2) + const newSource = createSource(source) + compilation.updateAsset(appJsonName, newSource) + const files = [ + { + ext: 'axml', + source: '' + }, + { + ext: 'js', + source: 'Component({onInit(){this.props.onPluginWrap(this)},didUnmount(){this.props.onPluginWrap(this,true)}})' + }, + { + ext: 'json', + source: '{"component":true}' + } + ] + files.forEach(({ ext, source }) => { + compilation.emitAsset(`${componentName}.${ext}`, createSource(source)) + }) + } + } +} diff --git a/packages/webpack-uni-mp-loader/lib/plugin/clear-style-file.js b/packages/webpack-uni-mp-loader/lib/plugin/clear-style-file.js new file mode 100644 index 0000000000000000000000000000000000000000..fae8fc5d5b113b7c4eff295df83832d3db22e1b1 --- /dev/null +++ b/packages/webpack-uni-mp-loader/lib/plugin/clear-style-file.js @@ -0,0 +1,33 @@ +const path = require('path') +const { + normalizePath, + getPlatformExts +} = require('@dcloudio/uni-cli-shared') +const { deleteAsset } = require('../shared') + +module.exports = function (compilation) { + // 移除部分含有错误引用的 wxss 文件 + const styleImports = {} + compilation.getAssets().forEach((asset) => { + const name = asset.name + const styleExtname = getPlatformExts().style + if (name.endsWith(styleExtname)) { + let origSource = asset.source.source() + origSource = origSource.trim ? origSource.trim() : '' + const result = origSource.match(/^@import ["'](.+?)["']$/) + if (result) { + const stylePath = normalizePath(path.join(path.dirname(name), result[1])) + if (compilation.getAsset(stylePath)) { + styleImports[stylePath] = styleImports[stylePath] || [] + styleImports[stylePath].push(name) + } else { + if (styleImports[name]) { + styleImports[name].forEach(name => deleteAsset(compilation, name)) + delete styleImports[name] + } + deleteAsset(compilation, name) + } + } + } + }) +} diff --git a/packages/webpack-uni-mp-loader/lib/plugin/generate-app.js b/packages/webpack-uni-mp-loader/lib/plugin/generate-app.js index 42f946def60de8deddac471222879a247a10ef1f..e44e4a5dede4536379dabdb79a4bac1fd5c4ba33 100644 --- a/packages/webpack-uni-mp-loader/lib/plugin/generate-app.js +++ b/packages/webpack-uni-mp-loader/lib/plugin/generate-app.js @@ -1,5 +1,6 @@ const { - getPlatformExts + getPlatformExts, + createSource } = require('../shared') const { @@ -22,26 +23,12 @@ module.exports = function generateApp (compilation) { process.env.UNI_PLATFORM !== 'app-plus' ) { const targetCssName = `common/main${ext}` - - if (!compilation.assets[targetCssName]) { - compilation.assets[targetCssName] = { - size () { - return Buffer.byteLength(getShadowCss(), 'utf8') - }, - source () { - return getShadowCss() - } - } + const asset = compilation.getAsset(targetCssName) + if (!asset) { + compilation.emitAsset(targetCssName, createSource(getShadowCss())) } else { - const source = compilation.assets[targetCssName].source() + getShadowCss() - compilation.assets[targetCssName] = { - size () { - return Buffer.byteLength(source, 'utf8') - }, - source () { - return source - } - } + const source = asset.source.source() + getShadowCss() + compilation.updateAsset(targetCssName, createSource(source)) } } @@ -50,17 +37,17 @@ module.exports = function generateApp (compilation) { const platforms = ['mp-weixin', 'mp-qq', 'mp-jd', 'mp-xhs', 'mp-toutiao', 'mp-lark'] const presetStyle = platforms.includes(process.env.UNI_PLATFORM) ? '[data-custom-hidden="true"],[bind-data-custom-hidden="true"]{display: none !important;}' : '' - if (compilation.assets[`common/main${ext}`]) { // 是否存在 main.css + if (compilation.getAsset(`common/main${ext}`)) { // 是否存在 main.css importMainCss = `@import './common/main${ext}';` } - if (compilation.assets[`common/vendor${ext}`]) { // 是否存在 vendor.css + if (compilation.getAsset(`common/vendor${ext}`)) { // 是否存在 vendor.css importVendorCss += `@import './common/vendor${ext}';` } const runtimeJsPath = 'common/runtime.js' - const asset = compilation.assets[runtimeJsPath] + const asset = compilation.getAsset(runtimeJsPath) if ( // app 和 baidu 不需要 process.env.UNI_PLATFORM !== 'app-plus' && process.env.UNI_PLATFORM !== 'mp-baidu' && @@ -70,13 +57,11 @@ module.exports = function generateApp (compilation) { const source = ` !function(){try{var a=Function("return this")();a&&!a.Math&&(Object.assign(a,{isFinite:isFinite,Array:Array,Date:Date,Error:Error,Function:Function,Math:Math,Object:Object,RegExp:RegExp,String:String,TypeError:TypeError,setTimeout:setTimeout,clearTimeout:clearTimeout,setInterval:setInterval,clearInterval:clearInterval}),"undefined"!=typeof Reflect&&(a.Reflect=Reflect))}catch(a){}}(); - ${asset.source()} + ${asset.source.source()} ` - const newSource = function () { - return source - } + const newSource = createSource(source) newSource.__$wrappered = true - compilation.assets[runtimeJsPath].source = newSource + compilation.updateAsset(runtimeJsPath, newSource) } const specialMethods = getSpecialMethods() diff --git a/packages/webpack-uni-mp-loader/lib/plugin/generate-component.js b/packages/webpack-uni-mp-loader/lib/plugin/generate-component.js index e6b0edb7621bd8d4c71b6c0e56c1f9c92b10000d..9a6dfa9df205df9b99688e72b49379a3c5c9fc05 100644 --- a/packages/webpack-uni-mp-loader/lib/plugin/generate-component.js +++ b/packages/webpack-uni-mp-loader/lib/plugin/generate-component.js @@ -3,8 +3,7 @@ const path = require('path') const webpack = require('webpack') const { removeExt, - normalizePath, - getPlatformExts + normalizePath } = require('@dcloudio/uni-cli-shared') const { getComponentSet @@ -15,7 +14,9 @@ const { } = require('@dcloudio/uni-cli-shared/lib/pages') const { - restoreNodeModules + restoreNodeModules, + createSource, + getModuleId } = require('../shared') const EMPTY_COMPONENT_LEN = 'Component({})'.length @@ -41,21 +42,21 @@ function findModule (modules, resource, altResource) { ) } -function findModuleId (modules, resource, altResource) { +function findModuleId (compilation, modules, resource, altResource) { const module = findModule(modules, resource, altResource) - return module && module.id + return module && getModuleId(compilation, module) } -function findModuleIdFromConcatenatedModules (modules, resource, altResource) { +function findModuleIdFromConcatenatedModules (compilation, modules, resource, altResource) { const module = modules.find(module => { return findModule(module.modules, resource, altResource) }) - return module && module.id + return module && getModuleId(compilation, module) } -function findComponentModuleId (modules, concatenatedModules, resource, altResource) { - return findModuleId(modules, resource, altResource) || - findModuleIdFromConcatenatedModules(concatenatedModules, resource, altResource) || +function findComponentModuleId (compilation, modules, concatenatedModules, resource, altResource) { + return findModuleId(compilation, modules, resource, altResource) || + findModuleIdFromConcatenatedModules(compilation, concatenatedModules, resource, altResource) || resource } @@ -66,20 +67,18 @@ module.exports = function generateComponent (compilation, jsonpFunction = 'webpa const componentChunkNameMap = {} const components = getComponentSet() if (components.size) { - const assets = compilation.assets - const modules = compilation.modules + const modules = Array.from(compilation.modules) const concatenatedModules = modules.filter(module => module.modules) let uniModule = modules.find(module => module.resource && normalizePath(module.resource) === uniPath) if (!uniModule && webpack.version[0] > 4) { uniModule = modules.find(module => module.rootModule && module.rootModule.resource && normalizePath(module.rootModule.resource) === uniPath) } - const uniModuleId = uniModule.id - const styleImports = {} - const fixSlots = {} + const uniModuleId = getModuleId(compilation, uniModule) const vueOuterComponentSting = 'vueOuterComponents' - Object.keys(assets).forEach(name => { + compilation.getAssets().forEach(asset => { + const name = asset.name // 判断是不是vue const isVueComponent = components.has(name.replace('.js', '')) // 独立分包外面的组件,复制到独立分包内,在components中看不到,所以需要单独处理 @@ -87,7 +86,7 @@ module.exports = function generateComponent (compilation, jsonpFunction = 'webpa if (isVueComponent || isVueOuterComponent) { curComponents.push(name.replace('.js', '')) - if (assets[name].source.__$wrappered) { + if (asset.source.__$wrappered) { return } @@ -103,13 +102,13 @@ module.exports = function generateComponent (compilation, jsonpFunction = 'webpa resource = normalizePath(path.resolve(process.env.UNI_CLI_CONTEXT, modulePath)) } - moduleId = findComponentModuleId(modules, concatenatedModules, resource, altResource) + moduleId = findComponentModuleId(compilation, modules, concatenatedModules, resource, altResource) } else { const resource = removeExt(path.resolve(process.env.UNI_INPUT_DIR, name)) - moduleId = findComponentModuleId(modules, concatenatedModules, resource) + moduleId = findComponentModuleId(compilation, modules, concatenatedModules, resource) } - const origSource = assets[name].source() + const origSource = asset.source.source() if (isVueComponent) { componentChunkNameMap[name] = moduleId @@ -148,191 +147,13 @@ module.exports = function generateComponent (compilation, jsonpFunction = 'webpa ]); ` ) - if (webpack.version[0] > 4) { - const { RawSource } = webpack.sources - const newSource = new RawSource(source) - compilation.updateAsset(name, newSource) - } else { - const newSource = function () { - return source - } - newSource.__$wrappered = true - assets[name].source = newSource - } - } - } - const styleExtname = getPlatformExts().style - if (name.endsWith(styleExtname)) { - // 移除部分含有错误引用的 wxss 文件 - let origSource = assets[name].source() - origSource = origSource.trim ? origSource.trim() : '' - const result = origSource.match(/^@import ["'](.+?)["']$/) - if (result) { - const stylePath = normalizePath(path.join(path.dirname(name), result[1])) - if (Object.keys(assets).includes(stylePath)) { - styleImports[stylePath] = styleImports[stylePath] || [] - styleImports[stylePath].push(name) - } else { - if (styleImports[name]) { - styleImports[name].forEach(name => delete assets[name]) - delete styleImports[name] - } - delete assets[name] - } - } - } - // 处理字节跳动|飞书小程序作用域插槽 - const fixExtname = '.fix' - if (name.endsWith(fixExtname)) { - const source = assets[name].source() - const [ownerName, parentName, componentName, slotName] = source.split(',') - const json = assets[ownerName + '.json'] - const jsonSource = json && json.source() - if (jsonSource) { - const data = JSON.parse(jsonSource) - const usingComponents = data.usingComponents || {} - const componentPath = normalizePath(path.relative('/', usingComponents[parentName])) - const slots = fixSlots[componentPath] = fixSlots[componentPath] || {} - const slot = slots[slotName] = slots[slotName] || {} - slot[componentName] = '/' + name.replace(fixExtname, '') - delete assets[name] - - const jsonFile = assets[`${componentPath}.json`] - if (jsonFile) { - const oldSource = jsonFile.__$oldSource || jsonFile.source() - const sourceObj = JSON.parse(oldSource) - Object.values(slots).forEach(components => { - const usingComponents = sourceObj.usingComponents = sourceObj.usingComponents || {} - Object.assign(usingComponents, components) - }) - delete sourceObj.componentGenerics - const source = JSON.stringify(sourceObj, null, 2) - if (webpack.version[0] > 4) { - const { RawSource } = webpack.sources - const newSource = new RawSource(source) - compilation.updateAsset(name, newSource) - } else { - jsonFile.source = function () { - return source - } - } - jsonFile.__$oldSource = oldSource - } - - const templateFile = assets[`${componentPath}${getPlatformExts().template}`] - if (templateFile) { - const oldSource = templateFile.__$oldSource || templateFile.source() - let templateSource - Object.keys(slots).forEach(name => { - const reg = new RegExp(`<${name} (.+?)>`) - templateSource = oldSource.replace(reg, string => { - const props = string.match(reg)[1] - return Object.keys(slots[name]).map(key => { - return `<${key} ${props}>` - }).join('') - }) - }) - if (webpack.version[0] > 4) { - const { RawSource } = webpack.sources - const newSource = new RawSource(templateSource) - compilation.updateAsset(name, newSource) - } else { - templateFile.source = function () { - return templateSource - } - } - templateFile.__$oldSource = oldSource - } + const newSource = createSource(source) + newSource.__$wrappered = true + compilation.updateAsset(name, newSource) } } }) } - // fix mp-qq https://github.com/dcloudio/uni-app/issues/2648 - const appJsonName = 'app.json' - const appJsonFile = compilation.assets[appJsonName] - if (process.env.UNI_PLATFORM === 'mp-qq' && appJsonFile) { - const obj = JSON.parse(appJsonFile.source()) - if (obj && obj.usingComponents && !Object.keys(obj.usingComponents).length) { - const componentName = 'fix-2648' - obj.usingComponents[componentName] = `/${componentName}` - const source = JSON.stringify(obj, null, 2) - if (webpack.version[0] > 4) { - const { RawSource } = webpack.sources - const newSource = new RawSource(source) - compilation.updateAsset(appJsonName, newSource) - } else { - appJsonFile.source = function () { - return source - } - } - const files = [ - { - ext: 'qml', - source: '' - }, - { - ext: 'js', - source: 'Component({})' - }, - { - ext: 'json', - source: '{"component":true}' - } - ] - files.forEach(({ ext, source }) => { - compilation.assets[`${componentName}.${ext}`] = { - size () { - return Buffer.byteLength(source, 'utf8') - }, - source () { - return source - } - } - }) - } - } - // fix mp-alipay plugin - if (process.env.UNI_PLATFORM === 'mp-alipay' && appJsonFile) { - const obj = JSON.parse(appJsonFile.source()) - const componentName = 'plugin-wrapper' - if (obj && obj.usingComponents && !(componentName in obj.usingComponents)) { - obj.usingComponents[componentName] = `/${componentName}` - const source = JSON.stringify(obj, null, 2) - if (webpack.version[0] > 4) { - const { RawSource } = webpack.sources - const newSource = new RawSource(source) - compilation.updateAsset(appJsonName, newSource) - } else { - appJsonFile.source = function () { - return source - } - } - const files = [ - { - ext: 'axml', - source: '' - }, - { - ext: 'js', - source: 'Component({onInit(){this.props.onPluginWrap(this)},didUnmount(){this.props.onPluginWrap(this,true)}})' - }, - { - ext: 'json', - source: '{"component":true}' - } - ] - files.forEach(({ ext, source }) => { - compilation.assets[`${componentName}.${ext}`] = { - size () { - return Buffer.byteLength(source, 'utf8') - }, - source () { - return source - } - } - }) - } - } if (process.env.UNI_FEATURE_OBSOLETE !== 'false') { if (lastComponents.length) { for (const name of lastComponents) { diff --git a/packages/webpack-uni-mp-loader/lib/plugin/generate-json.js b/packages/webpack-uni-mp-loader/lib/plugin/generate-json.js index f15a9efb369ee21d66e9962167cc4dd931ee81d3..76acf736a8f98808d3a8b787194372c858993a07 100644 --- a/packages/webpack-uni-mp-loader/lib/plugin/generate-json.js +++ b/packages/webpack-uni-mp-loader/lib/plugin/generate-json.js @@ -11,6 +11,8 @@ const { supportGlobalUsingComponents } = require('@dcloudio/uni-cli-shared/lib/cache') +const { createSource } = require('../shared') + // 主要解决 extends 且未实际引用的组件 const EMPTY_COMPONENT = 'Component({})' @@ -193,14 +195,7 @@ module.exports = function generateJson (compilation) { const scopedSlotComponentJsonSource = JSON.stringify(scopedSlotComponentJson, null, 2) scopedSlotComponents.forEach(scopedSlotComponent => { - compilation.assets[scopedSlotComponent] = { - size () { - return Buffer.byteLength(scopedSlotComponentJsonSource, 'utf8') - }, - source () { - return scopedSlotComponentJsonSource - } - } + compilation.emitAsset(scopedSlotComponent, createSource(scopedSlotComponentJsonSource)) }) } @@ -225,9 +220,9 @@ module.exports = function generateJson (compilation) { if (name === 'app.json') { // 删除manifest.json携带的配置项 delete jsonObj.insertAppCssToIndependent delete jsonObj.independent - delete jsonObj.copyWxComponentsOnDemand - if (process.env.UNI_PLATFORM === 'mp-weixin' && process.env.USE_UNI_AD) { - require('./mp-weixin-uniad-app.json')(jsonObj) + delete jsonObj.copyWxComponentsOnDemand + if (process.env.UNI_PLATFORM === 'mp-weixin' && process.env.USE_UNI_AD) { + require('./mp-weixin-uniad-app.json')(jsonObj) } } else { // 删除用于临时记录的属性 delete jsonObj.usingGlobalComponents @@ -259,26 +254,9 @@ function emit (name, jsonObj, compilation) { 'project.swan.js' ].includes( jsFile) && - !compilation.assets[jsFile] + !compilation.getAsset(jsFile) ) { - const jsFileAsset = { - size () { - return Buffer.byteLength(EMPTY_COMPONENT, 'utf8') - }, - source () { - return EMPTY_COMPONENT - } - } - compilation.assets[jsFile] = jsFileAsset - } - const jsonAsset = { - size () { - return Buffer.byteLength(source, 'utf8') - }, - source () { - return source - } + compilation.emitAsset(jsFile, createSource(EMPTY_COMPONENT)) } - - compilation.assets[name] = jsonAsset + compilation.emitAsset(name, createSource(source)) } diff --git a/packages/webpack-uni-mp-loader/lib/plugin/index-new.js b/packages/webpack-uni-mp-loader/lib/plugin/index-new.js index 984597dd0ed61a9b84f03f7da739cb5f0ae123df..b5dc643d2675ba9a50c956f9a3efa9c3600efb71 100644 --- a/packages/webpack-uni-mp-loader/lib/plugin/index-new.js +++ b/packages/webpack-uni-mp-loader/lib/plugin/index-new.js @@ -2,7 +2,6 @@ const path = require('path') const webpack = require('webpack') const { - md5, parseEntry, normalizePath } = require('@dcloudio/uni-cli-shared') @@ -11,25 +10,18 @@ const { pagesJsonJsFileName } = require('@dcloudio/uni-cli-shared/lib/pages') +const { createSource } = require('../shared') + const generateApp = require('./generate-app') const generateJson = require('./generate-json') const generateComponent = require('./generate-component') - -const emitFileCaches = {} +const clearStyleFile = require('./clear-style-file') +const mockGenericComponent = require('./mock-generic-component') +const addEmptyComponent = require('./add-empty-component') +const addPluginWrapper = require('./add-plugin-wrapper') function emitFile (filePath, source, compilation) { - const emitFileMD5 = md5(filePath + source) - if (emitFileCaches[filePath] !== emitFileMD5) { - emitFileCaches[filePath] = emitFileMD5 - compilation.assets[filePath] = { - size () { - return Buffer.byteLength(source, 'utf8') - }, - source () { - return source - } - } - } + compilation.emitAsset(filePath, createSource(source)) } function addSubPackagesRequire (compilation) { @@ -52,16 +44,9 @@ function addSubPackagesRequire (compilation) { if (!relativePath.startsWith('.')) { relativePath = './' + relativePath } - const source = `require('${relativePath}');` + compilation.assets[name].source() - - compilation.assets[name] = { - size () { - return Buffer.byteLength(source, 'utf8') - }, - source () { - return source - } - } + const source = `require('${relativePath}');` + compilation.getAsset(name).source.source() + + compilation.updateAsset(name, createSource(source)) } }) } @@ -76,49 +61,59 @@ function addMPPluginRequire (compilation) { assetsKeys.forEach(name => { const needProcess = process.env.UNI_MP_PLUGIN ? name === UNI_MP_PLUGIN_MAIN : UNI_MP_PLUGIN_EXPORT.includes(name) if (needProcess) { - const modules = compilation.modules - const orignalSource = compilation.assets[name].source() + const modules = Array.from(compilation.modules) + const orignalSource = compilation.getAsset(name).source.source() const globalEnv = process.env.UNI_PLATFORM === 'mp-alipay' ? 'my' : 'wx' const filePath = normalizePath(path.resolve(process.env.UNI_INPUT_DIR, name)) const uniModuleId = modules.find(module => module.resource && normalizePath(module.resource) === filePath).id const source = orignalSource + `\nmodule.exports = ${globalEnv}.__webpack_require_UNI_MP_PLUGIN__('${uniModuleId}');\n` - compilation.assets[name] = { - size () { - return Buffer.byteLength(source, 'utf8') - }, - source () { - return source - } - } + compilation.updateAsset(name, createSource(source)) } }) } -class WebpackUniMPPlugin { - apply (compiler) { - if (!process.env.UNI_USING_NATIVE && !process.env.UNI_USING_V3_NATIVE) { - compiler.hooks.emit.tapPromise('webpack-uni-mp-emit', compilation => { - return new Promise((resolve, reject) => { - addSubPackagesRequire(compilation) +function processAssets (compiler, compilation) { + addSubPackagesRequire(compilation) + + addMPPluginRequire(compilation) + + generateJson(compilation) - addMPPluginRequire(compilation) + // app.js,app.wxss + generateApp(compilation) + .forEach(({ + file, + source + }) => emitFile(file, source, compilation)) - generateJson(compilation) + generateComponent(compilation, compiler.options.output[webpack.version[0] > 4 ? 'chunkLoadingGlobal' : 'jsonpFunction']) - // app.js,app.wxss - generateApp(compilation) - .forEach(({ - file, - source - }) => emitFile(file, source, compilation)) + clearStyleFile(compilation) - generateComponent(compilation, compiler.options.output[webpack.version[0] > 4 ? 'chunkLoadingGlobal' : 'jsonpFunction']) + mockGenericComponent(compilation) + + addEmptyComponent(compilation) + + addPluginWrapper(compilation) +} - resolve() +class WebpackUniMPPlugin { + apply (compiler) { + if (!process.env.UNI_USING_NATIVE && !process.env.UNI_USING_V3_NATIVE) { + if (webpack.version[0] > 4) { + compiler.hooks.compilation.tap('WebpackUniMPPlugin', compilation => { + compilation.hooks.processAssets.tap({ + name: 'WebpackUniMPPlugin', + stage: webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL + }, (_) => { + processAssets(compiler, compilation) + }) }) - }) + } else { + compiler.hooks.emit.tap('webpack-uni-mp-emit', (compilation) => processAssets(compiler, compilation)) + } } compiler.hooks.invalid.tap('webpack-uni-mp-invalid', (fileName, changeTime) => { if ( diff --git a/packages/webpack-uni-mp-loader/lib/plugin/mock-generic-component.js b/packages/webpack-uni-mp-loader/lib/plugin/mock-generic-component.js new file mode 100644 index 0000000000000000000000000000000000000000..44dab67f92cebffa331d45d9b571a84c39b4f82f --- /dev/null +++ b/packages/webpack-uni-mp-loader/lib/plugin/mock-generic-component.js @@ -0,0 +1,61 @@ +const path = require('path') +const { + normalizePath, + getPlatformExts +} = require('@dcloudio/uni-cli-shared') +const { createSource, deleteAsset } = require('../shared') + +module.exports = function (compilation) { + // 处理字节跳动|飞书小程序作用域插槽 + const fixExtname = '.fix' + const fixSlots = {} + compilation.getAssets().forEach((asset) => { + const name = asset.name + if (name.endsWith(fixExtname)) { + const source = asset.source.source() + const [ownerName, parentName, componentName, slotName] = source.split(',') + const json = compilation.getAsset(ownerName + '.json') + const jsonSource = json && json.source.source() + if (jsonSource) { + const data = JSON.parse(jsonSource) + const usingComponents = data.usingComponents || {} + const componentPath = normalizePath(path.relative('/', usingComponents[parentName])) + const slots = fixSlots[componentPath] = fixSlots[componentPath] || {} + const slot = slots[slotName] = slots[slotName] || {} + slot[componentName] = '/' + name.replace(fixExtname, '') + deleteAsset(compilation, name) + + const jsonName = `${componentPath}.json` + const jsonFile = compilation.getAsset(jsonName) + if (jsonFile) { + const oldSource = jsonFile.source.source() + const sourceObj = JSON.parse(oldSource) + Object.values(slots).forEach(components => { + const usingComponents = sourceObj.usingComponents = sourceObj.usingComponents || {} + Object.assign(usingComponents, components) + }) + delete sourceObj.componentGenerics + const source = JSON.stringify(sourceObj, null, 2) + compilation.updateAsset(jsonName, createSource(source)) + } + + const templateName = `${componentPath}${getPlatformExts().template}` + const templateFile = compilation.getAsset(templateName) + if (templateFile) { + const oldSource = templateFile.source.source() + let templateSource = oldSource + Object.keys(slots).forEach(name => { + const reg = new RegExp(`<${name} (.+?)>`) + templateSource = oldSource.replace(reg, string => { + const props = string.match(reg)[1] + return Object.keys(slots[name]).map(key => { + return `<${key} ${props}>` + }).join('') + }) + }) + compilation.updateAsset(templateName, createSource(templateSource)) + } + } + } + }) +} diff --git a/packages/webpack-uni-mp-loader/lib/script-new.js b/packages/webpack-uni-mp-loader/lib/script-new.js index 828d4034ff2efbf3b77a73da8f0dd9dd0c885b79..85c6ad30edd9d3637211bbcfdf73651d629c80ea 100644 --- a/packages/webpack-uni-mp-loader/lib/script-new.js +++ b/packages/webpack-uni-mp-loader/lib/script-new.js @@ -28,7 +28,8 @@ const traverse = require('./babel/scoped-component-traverse') const { resolve, - normalizeNodeModules + normalizeNodeModules, + getIssuer } = require('./shared') const { @@ -55,13 +56,18 @@ module.exports = function (content, map) { type = 'Page' } //