From b71536125972358834c3c57b6f1a106945fc484b Mon Sep 17 00:00:00 2001 From: fxy060608 Date: Wed, 8 Jan 2020 14:34:28 +0800 Subject: [PATCH] feat(cli): tree-shaking with easycom --- packages/uni-cli-shared/lib/pages.js | 41 +++++++++++++++---- packages/vue-cli-plugin-uni-optimize/index.js | 5 +-- .../vue-cli-plugin-uni/lib/app-plus/index.js | 19 +++++---- packages/vue-cli-plugin-uni/lib/env.js | 6 ++- packages/vue-cli-plugin-uni/lib/h5/index.js | 3 ++ packages/vue-cli-plugin-uni/lib/mp.js | 3 ++ .../packages/vue-loader/lib/index.js | 19 ++++++++- .../webpack-uni-app-loader/plugin/index.js | 23 +++++++++++ 8 files changed, 96 insertions(+), 23 deletions(-) create mode 100644 packages/vue-cli-plugin-uni/packages/webpack-uni-app-loader/plugin/index.js diff --git a/packages/uni-cli-shared/lib/pages.js b/packages/uni-cli-shared/lib/pages.js index 403b40a37..a2666e8c9 100644 --- a/packages/uni-cli-shared/lib/pages.js +++ b/packages/uni-cli-shared/lib/pages.js @@ -330,17 +330,37 @@ const autoComponentMap = {} let lastUsingAutoImportComponentsJson = '' -process.UNI_AUTO_COMPONENTS = [] +let uniAutoImportComponents = [] + +let uniAutoImportScanComponents = [] + +function initAutoImportScanComponents () { + const componentsPath = path.resolve(process.env.UNI_INPUT_DIR, 'components') + const components = {} + try { + fs.readdirSync(componentsPath).forEach(name => { + if (fs.existsSync(path.resolve(componentsPath, name, name + '.vue'))) { + components[`^${name}$`] = `@/components/${name}/${name}.vue` + } else if (fs.existsSync(path.resolve(componentsPath, name, name + '.nvue'))) { + components[`^${name}$`] = `@/components/${name}/${name}.nvue` + } + }) + } catch (e) {} + + uniAutoImportScanComponents = parseUsingAutoImportComponents(components) + + refreshAutoComponentMap() +} function initAutoImportComponents (usingAutoImportComponents = {}) { // 目前仅 mp-weixin 内置支持 page-meta 等组件 if (process.env.UNI_PLATFORM !== 'mp-weixin') { - if (!usingAutoImportComponents['page-meta']) { - usingAutoImportComponents['page-meta'] = + if (!usingAutoImportComponents['^page-meta$']) { + usingAutoImportComponents['^page-meta$'] = '@dcloudio/uni-cli-shared/components/page-meta.vue' } - if (!usingAutoImportComponents['navigation-bar']) { - usingAutoImportComponents['navigation-bar'] = + if (!usingAutoImportComponents['^navigation-bar$']) { + usingAutoImportComponents['^navigation-bar$'] = '@dcloudio/uni-cli-shared/components/navigation-bar.vue' } } @@ -348,7 +368,7 @@ function initAutoImportComponents (usingAutoImportComponents = {}) { const newUsingAutoImportComponentsJson = JSON.stringify(usingAutoImportComponents) if (newUsingAutoImportComponentsJson !== lastUsingAutoImportComponentsJson) { lastUsingAutoImportComponentsJson = newUsingAutoImportComponentsJson - process.UNI_AUTO_COMPONENTS = parseUsingAutoImportComponents(usingAutoImportComponents) + uniAutoImportComponents = parseUsingAutoImportComponents(usingAutoImportComponents) refreshAutoComponentMap() } } @@ -363,8 +383,10 @@ function refreshAutoComponentMap () { } function addAutoComponent (name) { - const options = process.UNI_AUTO_COMPONENTS - const opt = options.find(opt => opt.pattern.test(name)) + let opt = uniAutoImportComponents.find(opt => opt.pattern.test(name)) + if (!opt) { + opt = uniAutoImportScanComponents.find(opt => opt.pattern.test(name)) + } if (!opt) { // 不匹配 return (autoComponentMap[name] = true) // cache } @@ -410,7 +432,8 @@ module.exports = { parsePagesJson, pagesJsonJsFileName, getAutoComponents, - initAutoImportComponents, + initAutoImportComponents, + initAutoImportScanComponents, addPageUsingComponents, getUsingComponentsCode, generateUsingComponentsCode, diff --git a/packages/vue-cli-plugin-uni-optimize/index.js b/packages/vue-cli-plugin-uni-optimize/index.js index 5622db980..33a66e3d7 100644 --- a/packages/vue-cli-plugin-uni-optimize/index.js +++ b/packages/vue-cli-plugin-uni-optimize/index.js @@ -80,11 +80,10 @@ module.exports = (api, options) => { webpackConfig.module .rule('vue') .use('vue-loader') - .loader(resolve('packages/vue-loader')) .tap(options => Object.assign(options, { + isH5TreeShaking: true, cacheDirectory: false, - cacheIdentifier: false, - compilerOptions: require('@dcloudio/vue-cli-plugin-uni/lib/h5/compiler-options') + cacheIdentifier: false })) .end() .uses diff --git a/packages/vue-cli-plugin-uni/lib/app-plus/index.js b/packages/vue-cli-plugin-uni/lib/app-plus/index.js index fff8e1686..e3e57ac44 100644 --- a/packages/vue-cli-plugin-uni/lib/app-plus/index.js +++ b/packages/vue-cli-plugin-uni/lib/app-plus/index.js @@ -11,6 +11,8 @@ const { getGlobalUsingComponentsCode } = require('@dcloudio/uni-cli-shared/lib/pages') +const WebpackUniAppPlugin = require('../../packages/webpack-uni-app-loader/plugin/index') + const { isUnaryTag, getPartialIdentifier @@ -36,7 +38,7 @@ function getProvides (isAppService) { 'getRegExp': [wxsPath, 'getRegExp'] } } - return { // app-view + return { // app-view '__f__': [path.resolve(__dirname, '../format-log.js'), 'default'], 'getDate': [wxsPath, 'getDate'], 'getRegExp': [wxsPath, 'getRegExp'] @@ -172,6 +174,7 @@ const v3 = { ] }, plugins: [ + new WebpackUniAppPlugin(), new webpack.ProvidePlugin(getProvides(isAppService)) ] } @@ -246,13 +249,13 @@ const v3 = { compilerOptions }, cacheConfig)) .end() - // .use('uniapp-custom-block-loader') - // .loader(require.resolve('@dcloudio/vue-cli-plugin-uni/packages/webpack-custom-block-loader')) - // .options({ - // isAppService, - // isAppView, - // compiler: getPlatformCompiler() - // }) + // .use('uniapp-custom-block-loader') + // .loader(require.resolve('@dcloudio/vue-cli-plugin-uni/packages/webpack-custom-block-loader')) + // .options({ + // isAppService, + // isAppView, + // compiler: getPlatformCompiler() + // }) // 是否启用 cache if (process.env.UNI_USING_CACHE) { diff --git a/packages/vue-cli-plugin-uni/lib/env.js b/packages/vue-cli-plugin-uni/lib/env.js index a5ebc9445..193b7a6af 100644 --- a/packages/vue-cli-plugin-uni/lib/env.js +++ b/packages/vue-cli-plugin-uni/lib/env.js @@ -312,9 +312,11 @@ if ( } const { - initAutoImportComponents + initAutoImportComponents, + initAutoImportScanComponents } = require('@dcloudio/uni-cli-shared/lib/pages') - + +initAutoImportScanComponents() initAutoImportComponents(pagesJsonObj.easycom) runByHBuilderX && console.log(`正在编译中...`) diff --git a/packages/vue-cli-plugin-uni/lib/h5/index.js b/packages/vue-cli-plugin-uni/lib/h5/index.js index f2ba59f7c..f1353f8ef 100644 --- a/packages/vue-cli-plugin-uni/lib/h5/index.js +++ b/packages/vue-cli-plugin-uni/lib/h5/index.js @@ -15,6 +15,8 @@ const modifyVueLoader = require('../vue-loader') const WebpackHtmlAppendPlugin = require('../../packages/webpack-html-append-plugin') +const WebpackUniAppPlugin = require('../../packages/webpack-uni-app-loader/plugin/index') + function resolve (dir) { return path.resolve(__dirname, '../../', dir) } @@ -41,6 +43,7 @@ function getProvides () { } const plugins = [ + new WebpackUniAppPlugin(), new webpack.ProvidePlugin(getProvides()) ] diff --git a/packages/vue-cli-plugin-uni/lib/mp.js b/packages/vue-cli-plugin-uni/lib/mp.js index f5c748ea7..c3ee0dd0e 100644 --- a/packages/vue-cli-plugin-uni/lib/mp.js +++ b/packages/vue-cli-plugin-uni/lib/mp.js @@ -8,6 +8,8 @@ const { getPlatformCssnano } = require('@dcloudio/uni-cli-shared') +const WebpackUniAppPlugin = require('../packages/webpack-uni-app-loader/plugin/index') + const modifyVueLoader = require('./vue-loader') const { @@ -157,6 +159,7 @@ module.exports = { }] }, plugins: [ + new WebpackUniAppPlugin(), createUniMPPlugin(), new webpack.ProvidePlugin(getProvides()) ] diff --git a/packages/vue-cli-plugin-uni/packages/vue-loader/lib/index.js b/packages/vue-cli-plugin-uni/packages/vue-loader/lib/index.js index a8f3b8702..46a938e2c 100644 --- a/packages/vue-cli-plugin-uni/packages/vue-loader/lib/index.js +++ b/packages/vue-cli-plugin-uni/packages/vue-loader/lib/index.js @@ -13,7 +13,7 @@ const componentNormalizerPath = require.resolve('./runtime/componentNormalizer') const { NS } = require('./plugin') let errorEmitted = false - +let modules // h5 平台摇树优化时,需要保留编译器原始modules(因为框架内代码不需要modules,开发者代码需要) function loadTemplateCompiler (loaderContext) { try { return require('vue-template-compiler') @@ -75,6 +75,23 @@ module.exports = function (source) { isAppNVue: options.isAppNVue }) + if (options.isH5TreeShaking) { // 摇树优化逻辑(框架组件移除样式,禁用 modules) + const isWin = /^win/.test(process.platform) + + const normalizePath = path => (isWin ? path.replace(/\\/g, '/') : path) + // fixed by xxxxxx + if(!modules && options.compilerOptions && options.compilerOptions.modules){ + modules = options.compilerOptions.modules + } + const sourcePath = normalizePath(require('@dcloudio/uni-h5/path').src) + if (normalizePath(this.resourcePath).indexOf(sourcePath) === 0) { + descriptor.styles.length = 0 + options.compilerOptions && (delete options.compilerOptions.modules) + } else if(options.compilerOptions){ + options.compilerOptions.modules = modules + } + } + // if the query has a type field, this is a language block request // e.g. foo.vue?type=template&id=xxxxx // and we will return early diff --git a/packages/vue-cli-plugin-uni/packages/webpack-uni-app-loader/plugin/index.js b/packages/vue-cli-plugin-uni/packages/webpack-uni-app-loader/plugin/index.js new file mode 100644 index 000000000..f1a22aa20 --- /dev/null +++ b/packages/vue-cli-plugin-uni/packages/webpack-uni-app-loader/plugin/index.js @@ -0,0 +1,23 @@ +const path = require('path') + +const { + normalizePath +} = require('@dcloudio/uni-cli-shared') + +const { + initAutoImportScanComponents +} = require('@dcloudio/uni-cli-shared/lib/pages') + +class WebpackUniAppPlugin { + apply(compiler) { + compiler.hooks.invalid.tap('webpack-uni-app-invalid', (fileName, changeTime) => { + if (fileName && typeof fileName === 'string') { + if (fileName.indexOf('.vue') !== -1 || fileName.indexOf('.nvue') !== -1) { + initAutoImportScanComponents() + } + } + }) + } +} + +module.exports = WebpackUniAppPlugin -- GitLab