From 6ef3306e54b1e2bfaec8ab39be43531774ab94fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8D=89=E9=9E=8B=E6=B2=A1=E5=8F=B7?= <308487730@qq.com> Date: Sun, 16 May 2021 19:53:54 +0800 Subject: [PATCH] fix: with esm2cjs to resolve dev BUG. --- package.json | 1 + script/plugins/index.ts | 110 ++++++++++++++++++++++++++++++++++++++++ script/plugins/utils.ts | 7 +++ script/utils.ts | 39 -------------- vite.config.ts | 17 ++++++- yarn.lock | 5 ++ 6 files changed, 138 insertions(+), 41 deletions(-) create mode 100644 script/plugins/index.ts create mode 100644 script/plugins/utils.ts diff --git a/package.json b/package.json index 9af7003..fb07c45 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "@types/minimist": "^1.2.1", "@vitejs/plugin-vue": "^1.2.2", "@vue/compiler-sfc": "^3.0.11", + "acorn": "^8.2.4", "chalk": "^4.1.0", "concurrently": "^6.0.0", "electron": "12.0.2", diff --git a/script/plugins/index.ts b/script/plugins/index.ts new file mode 100644 index 0000000..801dae0 --- /dev/null +++ b/script/plugins/index.ts @@ -0,0 +1,110 @@ +import fs from 'fs' +import path from 'path' +import acorn from 'acorn' +import { Plugin as RollupPlugin } from 'rollup' +import { Plugin as VitePlugin } from 'vite' +import { vue_js_ts_extensions } from './utils' + +/** + * cjs2esm + * @deprecated + */ +export function cjs2esm() { + return { + name: '@rollup/plugin-cjs2esm', + transform(code: string, filename: string) { + if (filename.includes(`${path.sep}node_modules${path.sep}`)) { + return code + } + + const cjsRegexp = /(const|let|var)[\n\s]+(\w+)[\n\s]*=[\n\s]*require\(["|'](.+)["|']\)/g + const res = code.match(cjsRegexp) + if (res) { + // const Store = require('electron-store') -> import Store from 'electron-store' + code = code.replace(cjsRegexp, `import $2 from '$3'`) + } + return code + }, + } +} + +/** esm2cjs */ +export function esm2cjs(needConvertModules: string[]): VitePlugin { + const filter = { + include: (id: string) => vue_js_ts_extensions.includes(path.parse(id).ext) + } + + return { + name: 'cxmh:esm2cjs', + transform(code, id) { + if (filter.include(id)) { + const node: any = acorn.parse(code, { + ecmaVersion: 'latest', + sourceType: 'module', + }) + + const parsed = path.parse(id) + + let codeRet = code + node.body.reverse().forEach((item) => { + console.log(item) + if (item.type !== 'ImportDeclaration') return + if (!needConvertModules.includes(item.source.value)) return // 跳过不要转换的模块 + + const statr = codeRet.substring(0, item.start) + const end = codeRet.substring(item.end) + const deft = item.specifiers.find(({ type }) => type === 'ImportDefaultSpecifier') + const deftModule = deft ? deft.local.name : '' + const nameAs = item.specifiers.find(({ type }) => type === 'ImportNamespaceSpecifier') + const nameAsModule = nameAs ? nameAs.local.name : '' + const modules = item. + specifiers + .filter((({ type }) => type === 'ImportSpecifier')) + .reduce((acc, cur) => acc.concat(cur.imported.name), []) + + // console.log(deftModule, '|', nameAsModule, '|', modules, '\n----') + + if (nameAsModule) { + // import * as name from + codeRet = `${statr}const ${nameAsModule} = require(${item.source.raw})${end}` + } else if (deftModule && !modules.length) { + // import name from 'mod' + codeRet = `${statr}const ${deftModule} = require(${item.source.raw})${end}` + } else if (deftModule && modules.length) { + // import name, { name2, name3 } from 'mod' + codeRet = `${statr}const ${deftModule} = require(${item.source.raw}) +const { ${modules.join(', ')} } = ${deftModule}${end}` + } else { + // import { name1, name2 } from 'mod' + codeRet = `${statr}const { ${modules.join(', ')} } = require(${item.source.raw})${end}` + } + }) + + fs.writeFileSync(path.join(__dirname, '.tmp/') + `${parsed.name + parsed.ext}.js`, codeRet) + + return codeRet + } + }, + } +} + +/** + * ensure cwd crrect + * TODO: __dirname 会被编译成字符串 + * @deprecated + */ +export function ensureCwdCrrect(filename: string): RollupPlugin { + return { + name: 'cxmh:ensure-cwd-crrect', + transform(code, id) { + if (id === filename) { + return ` +// !!! ensure cwd crrect +process.chdir(__dirname) + +${code} +` + } + }, + } +} diff --git a/script/plugins/utils.ts b/script/plugins/utils.ts new file mode 100644 index 0000000..8a56cf2 --- /dev/null +++ b/script/plugins/utils.ts @@ -0,0 +1,7 @@ + +/** HelloWorld.vue?vue&type=style&index=0&scoped=true&lang.css -> HelloWorld.vue */ +export function cleanUrl(url: string) { + return url.replace(/(\?|#).*$/, '') +} + +export const vue_js_ts_extensions = ['.vue', '.js', '.jsx', '.ts', '.tsx'] diff --git a/script/utils.ts b/script/utils.ts index 666f1ed..c838158 100644 --- a/script/utils.ts +++ b/script/utils.ts @@ -1,8 +1,6 @@ import { builtinModules } from 'module' -import { sep, join } from 'path' import { get } from 'http' import { green } from 'chalk' -import { Plugin } from 'rollup' /** 轮询监听 vite 启动 */ export function waitOn(arg0: { port: string | number; interval?: number; }) { @@ -22,42 +20,5 @@ export function waitOn(arg0: { port: string | number; interval?: number; }) { }) } -/** cjs2esm */ -export function cjs2esm() { - return { - name: '@rollup/plugin-cjs2esm', - transform(code: string, filename: string) { - if (filename.includes(`${sep}node_modules${sep}`)) { - return code - } - - const cjsRegexp = /(const|let|var)[\n\s]+(\w+)[\n\s]*=[\n\s]*require\(["|'](.+)["|']\)/g - const res = code.match(cjsRegexp) - if (res) { - // const Store = require('electron-store') -> import Store from 'electron-store' - code = code.replace(cjsRegexp, `import $2 from '$3'`) - } - return code - }, - } -} - -/** ensure cwd crrect */ -export function ensureCwdCrrect(filename: string): Plugin { - return { - name: 'cxmh:ensure-cwd-crrect', - transform(code, id) { - if (id === filename) { - return ` -// !!! ensure cwd crrect -process.chdir(__dirname) - -${code} -` - } - }, - } -} - /** node.js builtins module */ export const builtins = () => builtinModules.filter(x => !/^_|^(internal|v8|node-inspect)\/|\//.test(x)) diff --git a/vite.config.ts b/vite.config.ts index 1a2e18d..f3548b9 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -4,13 +4,23 @@ import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import { join } from 'path' // import typescript from '@rollup/plugin-typescript' -import { builtins, ensureCwdCrrect } from './script/utils' +import { builtins } from './script/utils' +import { + // ensureCwdCrrect, + esm2cjs, +} from './script/plugins' const root = join(__dirname, 'src/render') // https://vitejs.dev/config/ export default defineConfig({ - plugins: [vue()], + plugins: [ + vue(), + esm2cjs([ + 'electron', + 'electron-store', + ]), + ], root, base: './', // index.html 中静态资源加载位置 server: { @@ -24,6 +34,9 @@ export default defineConfig({ '@root': __dirname, }, }, + optimizeDeps: { + exclude: ['electron'], + }, build: { outDir: join(__dirname, 'dist/render'), emptyOutDir: true, diff --git a/yarn.lock b/yarn.lock index 78095d6..05331cd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -349,6 +349,11 @@ resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.0.11.tgz#20d22dd0da7d358bb21c17f9bde8628152642c77" integrity sha512-b+zB8A2so8eCE0JsxjL24J7vdGl8rzPQ09hZNhystm+KqSbKcAej1A+Hbva1rCMmTTqA+hFnUSDc5kouEo0JzA== +acorn@^8.2.4: + version "8.2.4" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.2.4.tgz#caba24b08185c3b56e3168e97d15ed17f4d31fd0" + integrity sha512-Ibt84YwBDDA890eDiDCEqcbwvHlBvzzDkU2cGBBDDI1QWT12jTiXIOn2CIw5KK4i6N5Z2HUxwYjzriDyqaqqZg== + ajv-formats@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-1.5.1.tgz#0f301b1b3846182f224cc563fc0a032daafb7dab"