Skip to content

Commit 9cacd59

Browse files
author
songyu
committed
feat: 支持微信小程序require.async()语法
1 parent e790289 commit 9cacd59

File tree

6 files changed

+134
-3
lines changed

6 files changed

+134
-3
lines changed

packages/uni-mp-weixin/lib/index.js

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
const createWxMpIndependentPlugins = require('./createIndependentPlugin')
3+
const RequireAsyncPlugin = require('./support-require-async/RequireAsyncPlugin')
4+
5+
module.exports = function createWxMpPlugins () {
6+
if (process.env.UNI_PLATFORM === 'mp-weixin') {
7+
return [
8+
...createWxMpIndependentPlugins(),
9+
new RequireAsyncPlugin()
10+
]
11+
}
12+
return []
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
const AsyncDependenciesBlock = require('webpack/lib/AsyncDependenciesBlock')
2+
const RequireAsyncDependency = require('./RequireAsyncDependency')
3+
4+
class RequireAsyncDependenciesBlock extends AsyncDependenciesBlock {
5+
constructor (request, range, groupOptions, module, loc, originModule) {
6+
super(groupOptions, module, loc, request)
7+
this.range = range
8+
const dep = new RequireAsyncDependency(request, originModule, this)
9+
dep.loc = loc
10+
this.addDependency(dep)
11+
}
12+
}
13+
14+
module.exports = class RequireAsyncDependenciesBlockParserPlugin {
15+
constructor (options) {
16+
this.options = options
17+
}
18+
19+
apply (parser) {
20+
parser.hooks.call
21+
.for('require.async').tap('RequireAsyncDependenciesBlockParserPlugin', expr => {
22+
const param = parser.evaluateExpression(expr.arguments[0])
23+
24+
const { options: importOptions } = parser.parseCommentOptions(expr.range)
25+
let chunkName = null
26+
if (importOptions && importOptions.webpackChunkName !== undefined) {
27+
chunkName = importOptions.webpackChunkName
28+
}
29+
const groupOptions = { name: chunkName }
30+
31+
const depBlock = new RequireAsyncDependenciesBlock(
32+
param.string,
33+
expr.range,
34+
groupOptions,
35+
parser.state.module,
36+
expr.loc,
37+
parser.state.module
38+
)
39+
40+
parser.state.current.addBlock(depBlock)
41+
return true
42+
})
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
const path = require('path')
2+
const ImportDependency = require('webpack/lib/dependencies/ImportDependency')
3+
4+
class RequireAsyncDependency extends ImportDependency {
5+
6+
};
7+
8+
RequireAsyncDependency.Template = class ImportDependencyTemplate {
9+
apply (dep, source, runtime) {
10+
let content = runtime.moduleExports({
11+
module: dep.module,
12+
request: dep.request
13+
})
14+
15+
// 目前只支持相对路径引用
16+
const relativePath = path.relative(dep.originModule.context, dep.module.userRequest)
17+
// 利用 require.async 加载分包中的资源,取代web环境下的 __webpack_require__.e(...)
18+
content = `require.async("${relativePath}").then(function(){return ${content} })`
19+
source.replace(dep.block.range[0], dep.block.range[1] - 1, content)
20+
}
21+
}
22+
23+
module.exports = RequireAsyncDependency
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
2+
const RequireAsyncDependenciesBlockParserPlugin = require('./RequireAsyncDependenciesBlockParserPlugin')
3+
const RequireAsyncDependency = require('./RequireAsyncDependency')
4+
5+
class RequireAsyncPlugin {
6+
constructor(options) {
7+
this.options = options
8+
}
9+
10+
apply(compiler) {
11+
const options = this.options
12+
compiler.hooks.compilation.tap('RequireAsyncPlugin',
13+
14+
(compilation, { normalModuleFactory }) => {
15+
compilation.dependencyFactories.set(RequireAsyncDependency, normalModuleFactory)
16+
compilation.dependencyTemplates.set(RequireAsyncDependency, new RequireAsyncDependency.Template())
17+
18+
const handler = (parser, parserOptions) => {
19+
new RequireAsyncDependenciesBlockParserPlugin(options).apply(parser)
20+
}
21+
22+
normalModuleFactory.hooks.parser.for('javascript/auto').tap('RequireAsyncDependenciesBlockParserPlugin', handler)
23+
normalModuleFactory.hooks.parser.for('javascript/dynamic').tap('RequireAsyncDependenciesBlockParserPlugin', handler)
24+
normalModuleFactory.hooks.parser.for('javascript/esm').tap('RequireAsyncDependenciesBlockParserPlugin', handler)
25+
}
26+
)
27+
}
28+
}
29+
module.exports = RequireAsyncPlugin

packages/vue-cli-plugin-uni/lib/mp/index.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ function createUniMPPlugin () {
2727
return new WebpackUniMPPlugin()
2828
}
2929

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

3232
const UniTips = require('./tips')
3333

@@ -192,7 +192,7 @@ module.exports = {
192192
new WebpackUniAppPlugin(),
193193
createUniMPPlugin(),
194194
new webpack.ProvidePlugin(getProvides()),
195-
...createWxMpIndependentPlugins()
195+
...createWxMpPlugins()
196196
]
197197

198198
if ((process.env.UNI_SUBPACKGE || process.env.UNI_MP_PLUGIN) && process.env.UNI_SUBPACKGE !== 'main') {
@@ -361,4 +361,4 @@ ${globalEnv}.__webpack_require_UNI_MP_PLUGIN__ = __webpack_require__;`
361361
webpackConfig.plugins.delete('preload')
362362
webpackConfig.plugins.delete('prefetch')
363363
}
364-
}
364+
}

packages/vue-cli-plugin-uni/lib/split-chunks.js

+22
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const independentFilter = ({ independent }) => independent
1010
const map2Root = ({ root }) => root + '/'
1111
const normalSubPackageRoots = subPkgsInfo.filter(normalFilter).map(map2Root)
1212
const independentSubpackageRoots = subPkgsInfo.filter(independentFilter).map(map2Root)
13+
const RequireAsyncDependency = require('@dcloudio/uni-mp-weixin/lib/support-require-async/RequireAsyncDependency')
1314

1415
function createCacheGroups () {
1516
const cacheGroups = {}
@@ -87,6 +88,13 @@ module.exports = function getSplitChunks () {
8788
if (module.type === 'css/mini-extract') {
8889
return false
8990
}
91+
92+
// require.async()的模块不应该被分割
93+
const reason = (module && module.reasons && module.reasons[0]) || {}
94+
if (reason.dependency instanceof RequireAsyncDependency) {
95+
return false
96+
}
97+
9098
if (module.resource && (
9199
module.resource.indexOf('.vue') !== -1 ||
92100
module.resource.indexOf('.nvue') !== -1 ||
@@ -139,6 +147,13 @@ module.exports = function getSplitChunks () {
139147
if (!baseTest(module)) {
140148
return false
141149
}
150+
151+
// require.async()的模块不应该被分割
152+
const reason = (module && module.reasons && module.reasons[0]) || {}
153+
if (reason.dependency instanceof RequireAsyncDependency) {
154+
return false
155+
}
156+
142157
chunks = getModuleChunks(module, chunks)
143158
const matchSubPackages = findSubPackages(chunks)
144159
const matchSubPackagesCount = matchSubPackages.size
@@ -220,6 +235,13 @@ module.exports = function getSplitChunks () {
220235
if (!baseTest(module)) {
221236
return false
222237
}
238+
239+
// require.async()的模块不应该被分割
240+
const reason = (module && module.reasons && module.reasons[0]) || {}
241+
if (reason.dependency instanceof RequireAsyncDependency) {
242+
return false
243+
}
244+
223245
chunks = getModuleChunks(module, chunks)
224246
const matchSubPackages = findSubPackages(chunks)
225247
if (

0 commit comments

Comments
 (0)