From 55f556105d3f80a3096c28d00a3c77dbb565e235 Mon Sep 17 00:00:00 2001 From: materbxh Date: Wed, 18 Oct 2023 15:39:30 +0800 Subject: [PATCH] feat: trans dep --- packages/vue-cli-plugin-mpx/config/babel.js | 126 ++++++++++++++++++ packages/vue-cli-plugin-mpx/config/base.js | 40 ------ .../vue-cli-plugin-mpx/generator/index.js | 1 + packages/vue-cli-plugin-mpx/index.js | 2 + yarn.lock | 25 +++- 5 files changed, 150 insertions(+), 44 deletions(-) create mode 100644 packages/vue-cli-plugin-mpx/config/babel.js diff --git a/packages/vue-cli-plugin-mpx/config/babel.js b/packages/vue-cli-plugin-mpx/config/babel.js new file mode 100644 index 00000000..623c78be --- /dev/null +++ b/packages/vue-cli-plugin-mpx/config/babel.js @@ -0,0 +1,126 @@ +const path = require('path') +const babel = require('@babel/core') +const { isWindows } = require('@vue/cli-shared-utils') + +function getDepPathRegex (dependencies) { + const deps = dependencies.map((dep) => { + if (typeof dep === 'string') { + const depPath = path.join('node_modules', dep, '/') + return isWindows + ? depPath.replace(/\\/g, '\\\\') // double escape for windows style path + : depPath + } else if (dep instanceof RegExp) { + return dep.source + } + + throw new Error( + 'transpileDependencies only accepts an array of string or regular expressions' + ) + }) + return deps.length ? new RegExp(deps.join('|')) : null +} + +/** @type {import('@vue/cli-service').ServicePlugin} */ +function resolveBabelConfig (api, options, config, target) { + const cliServicePath = path.dirname(require.resolve('@vue/cli-service')) + const mpxServicePath = path.dirname(require.resolve('@mpxjs/mpx-cli-service')) + + // try to load the project babel config; + // if the default preset is used, + // there will be a VUE_CLI_TRANSPILE_BABEL_RUNTIME env var set. + // the `filename` field is required + // in case there're filename-related options like `ignore` in the user config + babel.loadPartialConfigSync({ filename: api.resolve('src/main.js') }) + + const testPath = api.resolve('test') + const srcPath = api.resolve('src') + const jsRule = config.module + .rule('js') + .test(/\.m?jsx?$/) + .exclude.add((filepath) => { + const SHOULD_SKIP = true + const SHOULD_TRANSPILE = false + + // With data URI support in webpack 5, filepath could be undefined + if (!filepath) { + return SHOULD_SKIP + } + + // Always transpile js in vue files + if (/\.vue\.jsx?$/.test(filepath)) { + return SHOULD_TRANSPILE + } + // Exclude dynamic entries from cli-service + if (filepath.startsWith(cliServicePath) || filepath.startsWith(mpxServicePath)) { + return SHOULD_SKIP + } + + if (filepath.startsWith(testPath) || filepath.startsWith(srcPath)) { + return SHOULD_TRANSPILE + } + + if (/\.mpx\.js/.test(filepath)) { + return SHOULD_TRANSPILE + } + + // To transpile `@babel/runtime`, the config needs to be + // carefully adjusted to avoid infinite loops. + // So we only do the tranpilation when the special flag is on. + if (getDepPathRegex(['@babel/runtime']).test(filepath)) { + return process.env.VUE_CLI_TRANSPILE_BABEL_RUNTIME + ? SHOULD_TRANSPILE + : SHOULD_SKIP + } + + // if `transpileDependencies` is set to true, transpile all deps + if (options.transpileDependencies === true) { + // Some of the deps cannot be transpiled, though + // https://stackoverflow.com/a/58517865/2302258 + const NON_TRANSPILABLE_DEPS = [ + 'core-js', + 'webpack', + 'webpack-4', + 'css-loader', + 'mini-css-extract-plugin', + 'promise-polyfill', + 'html-webpack-plugin', + 'whatwg-fetch' + ] + const nonTranspilableDepsRegex = getDepPathRegex(NON_TRANSPILABLE_DEPS) + return nonTranspilableDepsRegex.test(filepath) + ? SHOULD_SKIP + : SHOULD_TRANSPILE + } + + // Otherwise, check if this is something the user explicitly wants to transpile + if (Array.isArray(options.transpileDependencies)) { + const transpileDepRegex = getDepPathRegex(options.transpileDependencies) + if (transpileDepRegex && transpileDepRegex.test(filepath)) { + return SHOULD_TRANSPILE + } + } + + // Don't transpile node_modules + return /node_modules/.test(filepath) ? SHOULD_SKIP : SHOULD_TRANSPILE + }) + .end() + + jsRule + .use('babel-loader') + .loader(require.resolve('babel-loader')) + .options({ + cacheCompression: false, + ...api.genCacheConfig( + 'babel-loader', + { + '@babel/core': require('@babel/core/package.json').version, + 'babel-loader': require('babel-loader/package.json').version, + modern: !!process.env.VUE_CLI_MODERN_BUILD, + browserslist: api.service.pkg.browserslist + }, + ['babel.config.js', '.browserslistrc'] + ) + }) +} + +module.exports.resolveBabelConfig = resolveBabelConfig diff --git a/packages/vue-cli-plugin-mpx/config/base.js b/packages/vue-cli-plugin-mpx/config/base.js index 5821a5be..036342ff 100644 --- a/packages/vue-cli-plugin-mpx/config/base.js +++ b/packages/vue-cli-plugin-mpx/config/base.js @@ -28,28 +28,6 @@ function changeStyleVueRuleToMpx (config, name) { store.set('mpx', value) } -/** - * 编译依赖 - * @param { (string|RegExp) [] } transpileDependencies - * @returns - */ -function genTranspileDepRegex (transpileDependencies) { - const path = require('path') - const { isWindows } = require('@vue/cli-shared-utils') - const deps = transpileDependencies.map((dep) => { - if (typeof dep === 'string') { - const depPath = path.join('node_modules', dep, '/') - return isWindows - ? depPath.replace(/\\/g, '\\\\') // double escape for windows style path - : depPath - } else if (dep instanceof RegExp) { - return dep.source - } - return '' - }) - return deps.length ? new RegExp(deps.join('|')) : null -} - /** * 获取 mpx webpack plugin 配置 * @param { import('@vue/cli-service').PluginAPI } api @@ -382,24 +360,6 @@ module.exports.resolveBaseConfig = function (api, options, config, target) { .use('mpx-wxs-pre-loader') .loader(require.resolve(MpxWebpackPlugin.wxsPreLoader().loader)) - const transpileDepRegex = genTranspileDepRegex( - options.transpileDependencies || [] - ) - - config.module - .rule('js') - .test(/\.js$/) - .include.add( - (filepath) => transpileDepRegex && transpileDepRegex.test(filepath) - ) - .add((filepath) => /\.mpx\.js/.test(filepath)) // 处理 mpx 转 web 的情况,vue-loader 会将 script block fake 出一个 .mpx.js 路径,用以 loader 的匹配 - .add(api.resolve('src')) - .add(/@mpxjs/) - .add(api.resolve('test')) - .end() - .use('babel-loader') - .loader(require.resolve('babel-loader')) - config.resolve.extensions.add('.mpx').add('.js').add('.wxml').add('.ts') config.resolve.modules.add('node_modules') diff --git a/packages/vue-cli-plugin-mpx/generator/index.js b/packages/vue-cli-plugin-mpx/generator/index.js index ecf23d4b..2c39aeee 100644 --- a/packages/vue-cli-plugin-mpx/generator/index.js +++ b/packages/vue-cli-plugin-mpx/generator/index.js @@ -37,6 +37,7 @@ module.exports = function (api, options) { vue: { // eslint-disable-next-line no-template-curly-in-string outputDir: '{outputDir}', + transpileDependencies: true, pluginOptions: { mpx: { plugin: { diff --git a/packages/vue-cli-plugin-mpx/index.js b/packages/vue-cli-plugin-mpx/index.js index 48137142..c0d15998 100644 --- a/packages/vue-cli-plugin-mpx/index.js +++ b/packages/vue-cli-plugin-mpx/index.js @@ -4,6 +4,7 @@ const { registerBuildCommand } = require('./commands/build') const { registerServeCommand } = require('./commands/serve') const { getCurrentTarget } = require('@mpxjs/cli-shared-utils') const path = require('path') +const { resolveBabelConfig } = require('./config/babel') function normalizeOutputPath (api, options, target) { const { outputDir } = options @@ -39,6 +40,7 @@ module.exports = function (api, options) { // 注入基础配置 api.chainWebpack((config) => { resolveBaseConfig(api, options, config, target) + resolveBabelConfig(api, options, config, target) }) } diff --git a/yarn.lock b/yarn.lock index 2dee64f9..95655f02 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5270,6 +5270,11 @@ buffer-from@^1.0.0: resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== +buffer-json@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/buffer-json/-/buffer-json-2.0.0.tgz#f73e13b1e42f196fe2fd67d001c7d7107edd7c23" + integrity sha512-+jjPFVqyfF1esi9fvfUs3NqM0pH1ziZ36VP4hmA/y/Ssfo/5w5xHKfTw9BwQjoJ1w/oVtpLomqwUHKdefGyuHw== + buffer@^5.2.0, buffer@^5.2.1, buffer@^5.5.0: version "5.7.1" resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" @@ -5378,6 +5383,18 @@ cache-content-type@^1.0.0: mime-types "^2.1.18" ylru "^1.2.0" +cache-loader@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/cache-loader/-/cache-loader-4.1.0.tgz#9948cae353aec0a1fcb1eafda2300816ec85387e" + integrity sha512-ftOayxve0PwKzBF/GLsZNC9fJBXl8lkZE3TOsjkboHfVHVkL39iUEs1FO07A33mizmci5Dudt38UZrrYXDtbhw== + dependencies: + buffer-json "^2.0.0" + find-cache-dir "^3.0.0" + loader-utils "^1.2.3" + mkdirp "^0.5.1" + neo-async "^2.6.1" + schema-utils "^2.0.0" + cacheable-request@^2.1.1: version "2.1.4" resolved "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d" @@ -8076,7 +8093,7 @@ find-cache-dir@^2.0.0: make-dir "^2.0.0" pkg-dir "^3.0.0" -find-cache-dir@^3.3.1: +find-cache-dir@^3.0.0, find-cache-dir@^3.3.1: version "3.3.2" resolved "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== @@ -11139,7 +11156,7 @@ loader-runner@^4.1.0, loader-runner@^4.2.0: resolved "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== -loader-utils@^1.0.2, loader-utils@^1.1.0: +loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3: version "1.4.2" resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz#29a957f3a63973883eb684f10ffd3d151fec01a3" integrity sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg== @@ -12108,7 +12125,7 @@ negotiator@0.6.3, negotiator@^0.6.2: resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== -neo-async@^2.5.0, neo-async@^2.6.2: +neo-async@^2.5.0, neo-async@^2.6.1, neo-async@^2.6.2: version "2.6.2" resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== @@ -14553,7 +14570,7 @@ saxes@^5.0.1: dependencies: xmlchars "^2.2.0" -schema-utils@^2.6.5: +schema-utils@^2.0.0, schema-utils@^2.6.5: version "2.7.1" resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==