提交 5883c2c5 编写于 作者: fxy060608's avatar fxy060608

feat(cli): add --subpackage

上级 6379990b
const path = require('path')
const {
runByHBuilderX,
runByHBuilderX,
isInHBuilderX
} = require('@dcloudio/uni-cli-shared')
......@@ -27,7 +27,8 @@ module.exports = (api, options) => {
'--watch': 'watch for changes',
'--minimize': 'Tell webpack to minimize the bundle using the TerserPlugin.',
'--auto-host': 'specify automator host',
'--auto-port': 'specify automator port'
'--auto-port': 'specify automator port',
'--subpackage': 'specify subpackage'
}
}, async (args) => {
for (const key in defaults) {
......@@ -36,6 +37,13 @@ module.exports = (api, options) => {
}
}
if (
args.subpackage &&
process.env.UNI_PLATFORM === 'mp-weixin'
) {
process.env.UNI_SUBPACKGE = args.subpackage
}
require('./util').initAutomator(args)
args.entry = args.entry || args._[0]
......@@ -164,12 +172,12 @@ async function build (args, api, options) {
if (!args.watch) {
const dirMsg = runByHBuilderX ? ''
: `The ${chalk.cyan(targetDirShort)} directory is ready to be deployed.`
done(`Build complete. ${dirMsg}`)
if (process.env.UNI_PLATFORM === 'h5' && !isInHBuilderX) {
console.log()
console.log('欢迎将H5站部署到uniCloud前端网页托管平台,高速、免费、安全、省心,详见:')
console.log('https://uniapp.dcloud.io/uniCloud/hosting')
done(`Build complete. ${dirMsg}`)
if (process.env.UNI_PLATFORM === 'h5' && !isInHBuilderX) {
console.log()
console.log('欢迎将H5站部署到uniCloud前端网页托管平台,高速、免费、安全、省心,详见:')
console.log('https://uniapp.dcloud.io/uniCloud/hosting')
}
} else {
const dirMsg = runByHBuilderX ? '' : `The ${chalk.cyan(targetDirShort)} directory is ready. `
......
......@@ -4,12 +4,15 @@ const webpack = require('webpack')
const {
parseEntry,
getMainEntry,
normalizePath,
getPlatformExts,
getPlatformCssnano
} = require('@dcloudio/uni-cli-shared')
const WebpackUniAppPlugin = require('../../packages/webpack-uni-app-loader/plugin/index')
const CustomModuleIdsPlugin = require('../../packages/webpack-custom-module-ids-plugin/index')
const modifyVueLoader = require('../vue-loader')
const {
......@@ -63,6 +66,88 @@ function getProvides () {
return provides
}
class PreprocessAssetsPlugin {
apply (compiler) {
compiler.hooks.emit.tap('PreprocessAssetsPlugin', compilation => {
const assets = compilation.assets
const hasVendor = assets['common/vendor.js']
Object.keys(assets).forEach(name => {
const extname = path.extname(name)
if (extname !== '.js') {
return
}
if (name.startsWith('common')) {
return
}
const dirname = path.dirname(name)
const runtimeJsCode = `require('${path.relative(dirname, 'common/runtime.js')}');`
const vendorJsCode = hasVendor ? `require('${path.relative(dirname, 'common/vendor.js')}');` : ''
const code = `${runtimeJsCode}${vendorJsCode}` + assets[name].source().toString()
assets[name] = {
size () {
return Buffer.byteLength(code, 'utf8')
},
source () {
return code
}
}
})
delete assets['common/main.js']
delete assets['app.js']
delete assets['app.json']
delete assets['app.wxss']
delete assets['project.config.json']
console.log(Object.keys(assets))
})
}
}
function initSubpackageConfig (webpackConfig, vueOptions) {
webpackConfig.node.set('global', false)
webpackConfig.plugins.delete('hash-module-ids')
// 与子包共享的模块
const sharedModules = {
'uni-mp-weixin/dist/index.js': 'uniWeixin',
'mp-vue/dist/mp.runtime.esm.js': 'uniVue'
}
const sharedModulePaths = Object.keys(sharedModules)
webpackConfig
.plugin('custom-hash-module-ids')
.use(CustomModuleIdsPlugin, [{
prefix: process.env.UNI_SUBPACKGE,
custom (libIdent) {
if (!libIdent) {
return
}
const normalizedLibIdent = normalizePath(libIdent)
const name = sharedModulePaths.find(p => normalizedLibIdent.endsWith(p))
if (name) {
return sharedModules[name]
}
}
}])
if (process.env.UNI_SUBPACKGE !== 'main') { // 非主包
process.env.UNI_OUTPUT_DIR = path.resolve(process.env.UNI_OUTPUT_DIR, process.env.UNI_SUBPACKGE)
vueOptions.outputDir = process.env.UNI_OUTPUT_DIR
webpackConfig.output.path(process.env.UNI_OUTPUT_DIR)
webpackConfig.output.jsonpFunction('webpackJsonp_' + process.env.UNI_SUBPACKGE)
webpackConfig.externals([
function (context, request, callback) {
if (request === 'vue') {
return callback(null, 'root global["webpackMain"]["uniVue"]')
}
const normalizedRequest = normalizePath(request)
const name = sharedModulePaths.find(p => normalizedRequest.endsWith(p))
if (name) {
return callback(null, `root global["webpackMain"]["${sharedModules[name]}"]`)
}
callback()
}
])
}
}
module.exports = {
vueConfig: {
parallel: false
......@@ -84,7 +169,23 @@ module.exports = {
const statCode = process.env.UNI_USING_STAT ? 'import \'@dcloudio/uni-stat\';' : ''
const beforeCode = 'import \'uni-pages\';'
let beforeCode = 'import \'uni-pages\';'
if (process.env.UNI_SUBPACKGE === 'main') {
const uniPath = require('@dcloudio/uni-cli-shared/lib/platform').getMPRuntimePath()
beforeCode +=
`import uniVue from 'vue';import * as uniWeixin from '${uniPath}';global['webpackMain']={uniVue,uniWeixin};`
}
const plugins = [
new WebpackUniAppPlugin(),
createUniMPPlugin(),
new webpack.ProvidePlugin(getProvides())
]
if (process.env.UNI_SUBPACKGE && process.env.UNI_SUBPACKGE !== 'main') {
plugins.push(new PreprocessAssetsPlugin())
}
return {
mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
......@@ -147,11 +248,7 @@ module.exports = {
}]
}]
},
plugins: [
new WebpackUniAppPlugin(),
createUniMPPlugin(),
new webpack.ProvidePlugin(getProvides())
]
plugins
}
},
chainWebpack (webpackConfig, vueOptions, api) {
......@@ -196,6 +293,10 @@ module.exports = {
}))
}
if (process.env.UNI_SUBPACKGE) {
initSubpackageConfig(webpackConfig, vueOptions)
}
webpackConfig.plugins.delete('hmr')
webpackConfig.plugins.delete('html')
webpackConfig.plugins.delete('copy')
......
const createHash = require('webpack/lib/util/createHash')
module.exports = class CustomModuleIdsPlugin {
constructor (options) {
this.options = Object.assign({
prefix: '',
hashFunction: 'md4',
hashDigest: 'base64',
hashDigestLength: 4
}, options || {})
}
apply (compiler) {
const options = this.options
compiler.hooks.compilation.tap('CustomModuleIdsPlugin', compilation => {
const usedIds = new Set()
compilation.hooks.beforeModuleIds.tap('CustomModuleIdsPlugin', modules => {
for (const module of modules) {
if (module.id !== null) {
continue
}
const libIdent = module.libIdent
? module.libIdent({
context: options.context || compiler.options.context
}) : null
let id = options.custom && options.custom(libIdent, module)
if (!id && libIdent) {
const hash = createHash(options.hashFunction)
hash.update(options.prefix + libIdent)
const hashId = (hash.digest(options.hashDigest))
let len = options.hashDigestLength
while (usedIds.has(hashId.substr(0, len))) len++
id = hashId.substr(0, len)
usedIds.add(id)
}
if (id) {
module.id = id
}
}
})
})
}
}
......@@ -61,7 +61,7 @@ function findComponentModuleId (modules, concatenatedModules, resource, altResou
let lastComponents = []
// TODO 解决方案不太理想
module.exports = function generateComponent (compilation) {
module.exports = function generateComponent (compilation, jsonpFunction = 'webpackJsonp') {
const curComponents = []
const components = getComponentSet()
if (components.size) {
......@@ -69,7 +69,9 @@ module.exports = function generateComponent (compilation) {
const modules = compilation.modules
const concatenatedModules = modules.filter(module => module.modules)
const uniModuleId = modules.find(module => module.resource && normalizePath(module.resource) === uniPath).id
const uniModule = !process.env.UNI_SUBPACKAGE && modules.find(module => module.resource && normalizePath(module.resource) ===
uniPath)
const uniModuleId = uniModule && uniModule.id
const styleImports = {}
const fixSlots = {}
......@@ -107,13 +109,19 @@ module.exports = function generateComponent (compilation) {
if (process.env.UNI_PLATFORM === 'mp-alipay') {
beforeCode = ';my.defineComponent || (my.defineComponent = Component);'
}
let requireCode =
`__webpack_require__('${uniModuleId}')['createComponent'](__webpack_require__(${JSON.stringify(moduleId)}))`
if (process.env.UNI_SUBPACKGE) {
requireCode =
`global['webpackMain']['uniWeixin']['createComponent'](__webpack_require__(${JSON.stringify(moduleId)}))`
}
const source = beforeCode + origSource +
`
;(${globalVar}["webpackJsonp"] = ${globalVar}["webpackJsonp"] || []).push([
;(${globalVar}["${jsonpFunction}"] = ${globalVar}["${jsonpFunction}"] || []).push([
'${chunkName}',
{
'${chunkName}':(function(module, exports, __webpack_require__){
__webpack_require__('${uniModuleId}')['createComponent'](__webpack_require__(${JSON.stringify(moduleId)}))
${requireCode}
})
},
[['${chunkName}']]
......@@ -230,4 +238,4 @@ function removeUnusedComponent (name) {
fs.renameSync(path.join(process.env.UNI_OUTPUT_DIR, name + '.json'), path.join(process.env.UNI_OUTPUT_DIR, name +
'.bak.json'))
} catch (e) {}
}
}
......@@ -85,6 +85,18 @@ function analyzeUsingComponents () {
// }, {})
}
function normalizeUsingComponents (file, usingComponents) {
const names = Object.keys(usingComponents)
if (!names.length) {
return usingComponents
}
file = path.dirname('/' + file)
names.forEach(name => {
usingComponents[name] = path.relative(file, usingComponents[name])
})
return usingComponents
}
module.exports = function generateJson (compilation) {
analyzeUsingComponents()
......@@ -167,6 +179,11 @@ module.exports = function generateJson (compilation) {
delete jsonObj.navigationBarShadow
}
if (process.env.UNI_SUBPACKGE && process.env.UNI_SUBPACKGE !== 'main') {
if (jsonObj.usingComponents) {
jsonObj.usingComponents = normalizeUsingComponents(name, jsonObj.usingComponents)
}
}
const source = JSON.stringify(jsonObj, null, 2)
const jsFile = name.replace('.json', '.js')
......@@ -208,4 +225,4 @@ module.exports = function generateJson (compilation) {
require('@dcloudio/uni-cli-shared/lib/cache').store()
}, 50)
}
}
}
......@@ -81,7 +81,7 @@ class WebpackUniMPPlugin {
source
}) => emitFile(file, source, compilation))
generateComponent(compilation)
generateComponent(compilation, compiler.options.output.jsonpFunction)
resolve()
})
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册