Skip to content

Commit

Permalink
feat: 支持微信小程序require.async()语法
Browse files Browse the repository at this point in the history
  • Loading branch information
songyu committed Mar 13, 2023
1 parent e790289 commit ec8a0ef
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 3 deletions.
13 changes: 13 additions & 0 deletions packages/uni-mp-weixin/lib/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

const createWxMpIndependentPlugins = require('./createIndependentPlugin')
const RequireAsyncPlugin = require('./support-require-async/RequireAsyncPlugin')

module.exports = function createWxMpPlugins () {
if (process.env.UNI_PLATFORM === 'mp-weixin') {
return [
...createWxMpIndependentPlugins(),
new RequireAsyncPlugin()
]
}
return []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const AsyncDependenciesBlock = require('webpack/lib/AsyncDependenciesBlock')
const RequireAsyncDependency = require('./RequireAsyncDependency')

class RequireAsyncDependenciesBlock extends AsyncDependenciesBlock {
constructor (request, range, groupOptions, module, loc, originModule) {
super(groupOptions, module, loc, request)
this.range = range
const dep = new RequireAsyncDependency(request, originModule, this)
dep.loc = loc
this.addDependency(dep)
}
}

module.exports = class RequireAsyncDependenciesBlockParserPlugin {
constructor (options) {
this.options = options
}

apply (parser) {
parser.hooks.call
.for('require.async').tap('RequireAsyncDependenciesBlockParserPlugin', expr => {
const param = parser.evaluateExpression(expr.arguments[0])

const { options: importOptions } = parser.parseCommentOptions(expr.range)
let chunkName = null
if (importOptions && importOptions.webpackChunkName !== undefined) {
chunkName = importOptions.webpackChunkName
}
const groupOptions = { name: chunkName }

const depBlock = new RequireAsyncDependenciesBlock(
param.string,
expr.range,
groupOptions,
parser.state.module,
expr.loc,
parser.state.module
)

parser.state.current.addBlock(depBlock)
return true
})
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const path = require('path')
const ImportDependency = require('webpack/lib/dependencies/ImportDependency')

class RequireAsyncDependency extends ImportDependency {

};

RequireAsyncDependency.Template = class ImportDependencyTemplate {
apply (dep, source, runtime) {
let content = runtime.moduleExports({
module: dep.module,
request: dep.request
})

// 目前只支持相对路径引用
const relativePath = path.relative(dep.originModule.context, dep.module.userRequest)
// 利用 require.async 加载分包中的资源,取代web环境下的 __webpack_require__.e(...)
content = `require.async("${relativePath}").then(function(){return ${content} })`
source.replace(dep.block.range[0], dep.block.range[1] - 1, content)
}
}

module.exports = RequireAsyncDependency
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

const RequireAsyncDependenciesBlockParserPlugin = require('./RequireAsyncDependenciesBlockParserPlugin')
const RequireAsyncDependency = require('./RequireAsyncDependency')

class RequireAsyncPlugin {
constructor (options) {
this.options = options
}

apply (compiler) {
const options = this.options
compiler.hooks.compilation.tap('RequireAsyncPlugin',

(compilation, { normalModuleFactory }) => {
compilation.dependencyFactories.set(RequireAsyncDependency, normalModuleFactory)
compilation.dependencyTemplates.set(RequireAsyncDependency, new RequireAsyncDependency.Template())

const handler = (parser, parserOptions) => {
new RequireAsyncDependenciesBlockParserPlugin(options).apply(parser)
}

normalModuleFactory.hooks.parser.for('javascript/auto').tap('RequireAsyncDependenciesBlockParserPlugin', handler)
normalModuleFactory.hooks.parser.for('javascript/dynamic').tap('RequireAsyncDependenciesBlockParserPlugin', handler)
normalModuleFactory.hooks.parser.for('javascript/esm').tap('RequireAsyncDependenciesBlockParserPlugin', handler)
}
)
}
}
module.exports = RequireAsyncPlugin
6 changes: 3 additions & 3 deletions packages/vue-cli-plugin-uni/lib/mp/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function createUniMPPlugin () {
return new WebpackUniMPPlugin()
}

const createWxMpIndependentPlugins = require('@dcloudio/uni-mp-weixin/lib/createIndependentPlugin')
const createWxMpPlugins = require('@dcloudio/uni-mp-weixin/lib/index')

const UniTips = require('./tips')

Expand Down Expand Up @@ -192,7 +192,7 @@ module.exports = {
new WebpackUniAppPlugin(),
createUniMPPlugin(),
new webpack.ProvidePlugin(getProvides()),
...createWxMpIndependentPlugins()
...createWxMpPlugins()
]

if ((process.env.UNI_SUBPACKGE || process.env.UNI_MP_PLUGIN) && process.env.UNI_SUBPACKGE !== 'main') {
Expand Down Expand Up @@ -361,4 +361,4 @@ ${globalEnv}.__webpack_require_UNI_MP_PLUGIN__ = __webpack_require__;`
webpackConfig.plugins.delete('preload')
webpackConfig.plugins.delete('prefetch')
}
}
}
22 changes: 22 additions & 0 deletions packages/vue-cli-plugin-uni/lib/split-chunks.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const independentFilter = ({ independent }) => independent
const map2Root = ({ root }) => root + '/'
const normalSubPackageRoots = subPkgsInfo.filter(normalFilter).map(map2Root)
const independentSubpackageRoots = subPkgsInfo.filter(independentFilter).map(map2Root)
const RequireAsyncDependency = require('@dcloudio/uni-mp-weixin/lib/support-require-async/RequireAsyncDependency')

function createCacheGroups () {
const cacheGroups = {}
Expand Down Expand Up @@ -87,6 +88,13 @@ module.exports = function getSplitChunks () {
if (module.type === 'css/mini-extract') {
return false
}

// require.async()的模块不应该被分割
const reason = (module && module.reasons && module.reasons[0]) || {}
if (reason.dependency instanceof RequireAsyncDependency) {
return false
}

if (module.resource && (
module.resource.indexOf('.vue') !== -1 ||
module.resource.indexOf('.nvue') !== -1 ||
Expand Down Expand Up @@ -139,6 +147,13 @@ module.exports = function getSplitChunks () {
if (!baseTest(module)) {
return false
}

// require.async()的模块不应该被分割
const reason = (module && module.reasons && module.reasons[0]) || {}
if (reason.dependency instanceof RequireAsyncDependency) {
return false
}

chunks = getModuleChunks(module, chunks)
const matchSubPackages = findSubPackages(chunks)
const matchSubPackagesCount = matchSubPackages.size
Expand Down Expand Up @@ -220,6 +235,13 @@ module.exports = function getSplitChunks () {
if (!baseTest(module)) {
return false
}

// require.async()的模块不应该被分割
const reason = (module && module.reasons && module.reasons[0]) || {}
if (reason.dependency instanceof RequireAsyncDependency) {
return false
}

chunks = getModuleChunks(module, chunks)
const matchSubPackages = findSubPackages(chunks)
if (
Expand Down

0 comments on commit ec8a0ef

Please sign in to comment.