Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 支持微信小程序require.async()语法 #4197

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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