You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
137 lines
3.5 KiB
137 lines
3.5 KiB
const path = require('path')
|
|
|
|
const parser = require('@babel/parser')
|
|
|
|
const {
|
|
removeExt,
|
|
hyphenate,
|
|
normalizePath,
|
|
getComponentName,
|
|
jsPreprocessOptions
|
|
} = require('@dcloudio/uni-cli-shared')
|
|
|
|
const {
|
|
getBabelParserOptions
|
|
} = require('@dcloudio/uni-cli-shared/lib/platform')
|
|
|
|
const {
|
|
isBuiltInComponentPath
|
|
} = require('@dcloudio/uni-cli-shared/lib/pages')
|
|
|
|
const {
|
|
updateUsingComponents
|
|
} = require('@dcloudio/uni-cli-shared/lib/cache')
|
|
|
|
const preprocessor = require('@dcloudio/vue-cli-plugin-uni/packages/webpack-preprocess-loader/preprocess')
|
|
|
|
const traverse = require('./babel/scoped-component-traverse')
|
|
|
|
const {
|
|
resolve,
|
|
normalizeNodeModules
|
|
} = require('./shared')
|
|
|
|
const {
|
|
findBabelLoader,
|
|
addDynamicImport
|
|
} = require('./babel/util')
|
|
|
|
module.exports = function (content, map) {
|
|
this.cacheable && this.cacheable()
|
|
|
|
content = preprocessor.preprocess(content, jsPreprocessOptions.context, {
|
|
type: jsPreprocessOptions.type
|
|
})
|
|
|
|
let resourcePath = normalizeNodeModules(removeExt(normalizePath(path.relative(process.env.UNI_INPUT_DIR, this
|
|
.resourcePath))))
|
|
|
|
let type = ''
|
|
if (resourcePath === 'App') {
|
|
type = 'App'
|
|
} else if (process.UNI_ENTRY[resourcePath]) {
|
|
type = 'Page'
|
|
}
|
|
// <script src=""/>
|
|
if (!type && this._module.issuer && this._module.issuer.issuer) {
|
|
resourcePath = normalizeNodeModules(removeExt(normalizePath(path.relative(process.env.UNI_INPUT_DIR, this._module
|
|
.issuer.issuer.resource))))
|
|
if (resourcePath === 'App') {
|
|
type = 'App'
|
|
} else if (process.UNI_ENTRY[resourcePath]) {
|
|
type = 'Page'
|
|
}
|
|
}
|
|
|
|
if ( // windows 上 page-meta, navigation-bar 可能在不同盘上
|
|
/^win/.test(process.platform) &&
|
|
path.isAbsolute(resourcePath) &&
|
|
isBuiltInComponentPath(resourcePath)
|
|
) {
|
|
resourcePath = normalizePath(path.relative(process.env.UNI_CLI_CONTEXT, resourcePath))
|
|
}
|
|
|
|
if (!type) {
|
|
type = 'Component'
|
|
}
|
|
|
|
const {
|
|
state: {
|
|
components
|
|
}
|
|
} = traverse(parser.parse(content, getBabelParserOptions()), {
|
|
type,
|
|
components: []
|
|
})
|
|
|
|
const callback = this.async()
|
|
|
|
if (!components.length) {
|
|
if (type === 'App') {
|
|
callback(null, content, map)
|
|
return
|
|
}
|
|
// 防止组件从有到无,App.vue 中不支持使用组件
|
|
updateUsingComponents(resourcePath, Object.create(null), type)
|
|
callback(null, content, map)
|
|
return
|
|
}
|
|
|
|
const dynamicImports = Object.create(null)
|
|
Promise.all(components.map(component => {
|
|
return resolve.call(this, component.source).then(resolved => {
|
|
component.name = getComponentName(hyphenate(component.name))
|
|
const source = component.source
|
|
component.source = normalizeNodeModules(removeExt(path.relative(process.env.UNI_INPUT_DIR,
|
|
resolved)))
|
|
// 非页面组件才需要 dynamic import
|
|
if (!process.UNI_ENTRY[component.source]) {
|
|
dynamicImports[source] = {
|
|
identifier: component.value,
|
|
chunkName: component.source,
|
|
source: source
|
|
}
|
|
}
|
|
})
|
|
})).then(() => {
|
|
const usingComponents = Object.create(null)
|
|
components.forEach(({
|
|
name,
|
|
source
|
|
}) => {
|
|
usingComponents[name] = `/${source}`
|
|
})
|
|
|
|
const babelLoader = findBabelLoader(this.loaders)
|
|
if (!babelLoader) {
|
|
callback(new Error('babel-loader 查找失败'), content)
|
|
} else {
|
|
addDynamicImport(babelLoader, resourcePath, dynamicImports)
|
|
|
|
updateUsingComponents(resourcePath, usingComponents, type)
|
|
callback(null, content, map)
|
|
}
|
|
}, err => {
|
|
callback(err, content, map)
|
|
})
|
|
}
|
|
|