const t = require('@babel/types') const uniI18n = require('@dcloudio/uni-cli-i18n') const hyphenateRE = /\B([A-Z])/g function cached (fn) { const cache = Object.create(null) return function cachedFn (str) { const hit = cache[str] return hit || (cache[str] = fn(str)) } } const hyphenate = cached((str) => { return str.replace(hyphenateRE, '-$1').toLowerCase() }) function findImportDeclaration (identifierName, path) { const binding = path.scope.getBinding(identifierName) if (!binding) { return } if (t.isImportDeclaration(binding.path.parent)) { return binding.path.parentPath } } function parseComponents (names, path) { const components = [] const dynamicImportMap = new Map() names.forEach(({ name, value }) => { const importDeclaration = findImportDeclaration(value, path) if (!importDeclaration) { throw new Error(uniI18n.__('mpLoader.componentReferenceErrorOnlySupportImport', { 0: name })) } let source = importDeclaration.node.source.value if (process.UNI_LIBRARIES && process.UNI_LIBRARIES.includes(source)) { const componentName = hyphenate(name) source = source + '/lib/' + componentName + '/' + componentName } const dynamicImportArray = dynamicImportMap.get(importDeclaration) || [] dynamicImportArray.push({ name, value, source }) dynamicImportMap.set(importDeclaration, dynamicImportArray) }) const importDeclarations = dynamicImportMap.keys() for (const importDeclaration of importDeclarations) { const dynamicImportArray = dynamicImportMap.get(importDeclaration) dynamicImportArray.forEach((dynamicImport) => { components.push(dynamicImport) }) importDeclaration.remove() } return components } function findBabelLoader (loaders) { return loaders.find(loader => loader.path.indexOf('babel-loader') !== -1) } const babelPluginDynamicImport = require.resolve('./plugin-dynamic-import') function addDynamicImport (babelLoader, resourcePath, dynamicImports) { babelLoader.options = babelLoader.options || {} if (!babelLoader.options.plugins) { babelLoader.options.plugins = [] } babelLoader.options.plugins.push([babelPluginDynamicImport, { resourcePath, dynamicImports }]) } module.exports = { addDynamicImport, findBabelLoader, parseComponents }