diff --git a/packages/canvas/vite.config.js b/packages/canvas/vite.config.js index 1f4a573..e04a41f 100644 --- a/packages/canvas/vite.config.js +++ b/packages/canvas/vite.config.js @@ -23,9 +23,6 @@ export default defineConfig({ '@': path.resolve(__dirname, 'src') } }, - define: { - 'process.env': {} - }, plugins: [ vue({ template: { diff --git a/packages/common/vite.config.js b/packages/common/vite.config.js index fbd436c..030c391 100644 --- a/packages/common/vite.config.js +++ b/packages/common/vite.config.js @@ -20,9 +20,6 @@ export default defineConfig({ plugins: [vue(), vueJsx()], publicDir: false, resolve: {}, - define: { - 'process.env': {} - }, build: { cssCodeSplit: false, lib: { diff --git a/packages/controller/js/ast.js b/packages/controller/js/ast.js index 18026c0..c9e7d74 100644 --- a/packages/controller/js/ast.js +++ b/packages/controller/js/ast.js @@ -17,6 +17,7 @@ import prettier from 'prettier' import parserHtml from 'prettier/parser-html' import parseCss from 'prettier/parser-postcss' import parserBabel from 'prettier/parser-babel' +import prettierConfig from './config-files/prettierrc' const METHOD_REGEXP = /function.*?\(/ @@ -33,10 +34,7 @@ const formatScript = (string) => { const options = { parser: 'babel', plugins: [parserBabel], - printWidth: 120, - singleQuote: true, - semi: false, - trailingComma: 'none' + ...prettierConfig } try { // 低码中的编辑器大多只会输入js值,并不是一个完整的javascript表达式,无法格式化,因此需要特殊处理预格式化该种情形 @@ -53,21 +51,21 @@ const formatJson = (string) => parser: 'json', plugins: [parserBabel], trailingComma: 'es5', - tabWidth: 2, - semi: false, - singleQuote: true + ...prettierConfig }) const formatHtml = (string) => prettier.format(string, { parser: 'html', - plugins: [parserBabel, parserHtml] + plugins: [parserBabel, parserHtml], + ...prettierConfig }) const formatCss = (string) => prettier.format(string, { parser: 'css', - plugins: [parseCss] + plugins: [parseCss], + ...prettierConfig }) const formatterMap = { diff --git a/packages/controller/js/config-files/eslint-rule.js b/packages/controller/js/config-files/eslint-rule.js new file mode 100644 index 0000000..ad64125 --- /dev/null +++ b/packages/controller/js/config-files/eslint-rule.js @@ -0,0 +1,8 @@ +import eslintRecommended from '@eslint/js/src/configs/eslint-recommended.js' +export default { + ...eslintRecommended.rules, + 'no-console': 'error', + 'no-debugger': 'error', + 'space-before-function-paren': 'off', + 'no-use-before-define': 'error' +} diff --git a/packages/controller/js/config-files/prettierrc.js b/packages/controller/js/config-files/prettierrc.js new file mode 100644 index 0000000..4fcde65 --- /dev/null +++ b/packages/controller/js/config-files/prettierrc.js @@ -0,0 +1,8 @@ +export default { + semi: false, + singleQuote: true, + printWidth: 120, + trailingComma: 'none', + endOfLine: 'auto', + tabWidth: 2 +} diff --git a/packages/controller/js/linter.js b/packages/controller/js/linter.js index 14e9e7e..edfb3f1 100644 --- a/packages/controller/js/linter.js +++ b/packages/controller/js/linter.js @@ -1,27 +1,29 @@ /** -* Copyright (c) 2023 - present TinyEngine Authors. -* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd. -* -* Use of this source code is governed by an MIT-style license. -* -* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, -* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR -* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. -* -*/ + * Copyright (c) 2023 - present TinyEngine Authors. + * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd. + * + * Use of this source code is governed by an MIT-style license. + * + * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, + * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR + * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. + * + */ -import { PROD, BASE_URL } from './environments' +import eslintWorkerUrl from './worker-files/eslint.worker?worker&url' export const initLinter = (editor, monacoInstance, state) => { - let workerUrl = `${BASE_URL}monaco-linter/eslint.worker.js` + let workerUrl = new URL(eslintWorkerUrl, import.meta.url) // 线上环境,存在 worker 资源跨域的情况 - if (PROD) { - const workerBlob = new Blob([`importScripts('${workerUrl}');`], { type: 'application/javascript' }) + if (workerUrl.origin !== location.origin) { + const workerBlob = new Blob([`import('${workerUrl}');`], { + type: 'application/javascript' + }) workerUrl = window.URL.createObjectURL(workerBlob) } - const worker = new Worker(workerUrl) + const worker = new Worker(workerUrl, { type: 'module' }) // 监听 ESLint web worker 的返回 worker.onmessage = function (event) { diff --git a/packages/controller/js/worker-files/eslint.worker.js b/packages/controller/js/worker-files/eslint.worker.js new file mode 100644 index 0000000..7d6e79e --- /dev/null +++ b/packages/controller/js/worker-files/eslint.worker.js @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2023 - present TinyEngine Authors. + * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd. + * + * Use of this source code is governed by an MIT-style license. + * + * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, + * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR + * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. + * + */ + +import { Linter } from 'eslint-linter-browserify' +import eslintRule from '../config-files/eslint-rule' + +const defaultConfig = { + env: { + browser: true, + es6: true + }, + parserOptions: { + ecmaFeatures: { + jsx: true + }, + ecmaVersion: 'latest', + sourceType: 'module' + } +} + +const config = { + ...defaultConfig, + rules: { + ...eslintRule, + // JS 面板中,仅定义 function,但可能不使用该方法 + 'no-unused-vars': 'off', + 'no-alert': 'off', + 'no-console': 'off' + }, + settings: {} +} + +// 错误的等级,ESLint 与 monaco 的存在差异,做一层映射 +const severityMap = { + 2: 'Error', + 1: 'Warning' +} +const linter = new Linter() + +self.addEventListener('message', (event) => { + const { code, version } = event.data + + const ruleDefines = linter.getRules() + const errs = linter.verify(code, config) + + const markers = errs.map(({ ruleId = '', line, endLine, column, endColumn, message, severity }) => ({ + code: { + value: ruleId || '', + target: ruleDefines.get(ruleId)?.meta?.docs?.url || '' + }, + startLineNumber: line, + endLineNumber: endLine, + startColumn: column, + endColumn: endColumn, + message: message, + severity: severityMap[severity], + source: 'ESLint' + })) + + // ESLint 静态检查结果,发回主线程 + self.postMessage({ markers, version }) +}) diff --git a/packages/controller/package.json b/packages/controller/package.json index b247c6f..e5f5ed4 100644 --- a/packages/controller/package.json +++ b/packages/controller/package.json @@ -43,6 +43,7 @@ "@opentiny/vue-renderless": "~3.10.0", "@vue/shared": "^3.3.4", "css-tree": "^2.3.1", + "eslint-linter-browserify": "8.57.0", "prettier": "2.7.1" }, "devDependencies": { diff --git a/packages/controller/vite.config.js b/packages/controller/vite.config.js index c8fb29f..d0c79a4 100644 --- a/packages/controller/vite.config.js +++ b/packages/controller/vite.config.js @@ -17,7 +17,7 @@ import vueJsx from '@vitejs/plugin-vue-jsx' import { glob } from 'glob' import { fileURLToPath } from 'node:url' -const jsEntries = glob.sync('./js/**.js').map((file) => { +const jsEntries = glob.sync('./js/**/*.js').map((file) => { return [file.slice(0, file.length - path.extname(file).length), fileURLToPath(new URL(file, import.meta.url))] }) @@ -26,8 +26,8 @@ export default defineConfig({ plugins: [vue(), vueJsx()], publicDir: false, resolve: {}, + base: './', define: { - 'process.env': {}, 'import.meta': 'import.meta', 'import.meta.env.MODE': 'import.meta.env.MODE', 'import.meta.env.PROD': 'import.meta.env.PROD', diff --git a/packages/design-core/package.json b/packages/design-core/package.json index c33e5d0..9020860 100644 --- a/packages/design-core/package.json +++ b/packages/design-core/package.json @@ -85,6 +85,7 @@ "@vue/repl": "^2.9.0", "@vueuse/core": "^9.6.0", "element-resize-detector": "^1.2.4", + "eslint-linter-browserify": "8.57.0", "file-saver": "^2.0.5", "html2canvas": "^1.4.1", "jszip": "^3.10.1", diff --git a/packages/design-core/public/monaco-linter/eslint.worker.js b/packages/design-core/public/monaco-linter/eslint.worker.js deleted file mode 100644 index 05cf20d..0000000 --- a/packages/design-core/public/monaco-linter/eslint.worker.js +++ /dev/null @@ -1,57 +0,0 @@ -/** -* Copyright (c) 2023 - present TinyEngine Authors. -* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd. -* -* Use of this source code is governed by an MIT-style license. -* -* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, -* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR -* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. -* -*/ - -// importScripts 不支持 esm, 此处使用 umd, 对外暴露的变量名:linter,需要填写openTiny的cdn地址 -importScripts('') - -// 根据公司的编码规范内置了 config/rules, 可以进一步定制 -const config = { - ...self.linter.config, - rules: { - ...self.linter.config.rules, - // JS 面板中,仅定义 function,但可能不使用该方法 - 'no-unused-vars': 'off', - 'no-alert': 'off', - 'no-console': 'off' - }, - settings: {} -} - -// 错误的等级,ESLint 与 monaco 的存在差异,做一层映射 -const severityMap = { - 2: 'Error', - 1: 'Warning' -} - -self.addEventListener('message', (event) => { - const { code, version } = event.data - - const ruleDefines = self.linter.esLinter.getRules() - const errs = self.linter.esLinter.verify(code, config) - - const markers = errs.map(({ ruleId = '', line, endLine, column, endColumn, message, severity }) => ({ - code: { - value: ruleId, - target: ruleDefines.get(ruleId)?.meta?.docs?.url - }, - startLineNumber: line, - endLineNumber: endLine, - startColumn: column, - endColumn: endColumn, - message: message, - severity: severityMap[severity], - source: 'ESLint' - })) - - // ESLint 静态检查结果,发回主线程 - self.postMessage({ markers, version }) -}) diff --git a/packages/design-core/vite.config.js b/packages/design-core/vite.config.js index 4aea414..6dde1bc 100644 --- a/packages/design-core/vite.config.js +++ b/packages/design-core/vite.config.js @@ -93,9 +93,6 @@ const config = { ] } }, - define: { - 'process.env': {} - }, build: { commonjsOptions: { transformMixedEsModules: true, diff --git a/packages/toolbars/generate-vue/src/generateCode.js b/packages/toolbars/generate-vue/src/generateCode.js index ed30161..db09d40 100644 --- a/packages/toolbars/generate-vue/src/generateCode.js +++ b/packages/toolbars/generate-vue/src/generateCode.js @@ -14,6 +14,7 @@ import prettier from 'prettier' import parserHtml from 'prettier/parser-html' import parseCss from 'prettier/parser-postcss' import parserBabel from 'prettier/parser-babel' +import prettierCommon from '@opentiny/tiny-engine-controller/js/config-files/prettierrc' // LOWCODE_TODO: 从本地配置文件获取 const basePaths = { @@ -36,13 +37,6 @@ const FILE_TYPES = { Store: 'Store' } -const prettierCommon = { - printWidth: 120, - semi: false, - singleQuote: true, - trailingComma: 'none' -} - function formatScript(string) { return prettier.format(string, { ...prettierCommon, diff --git a/packages/vue-generator/package.json b/packages/vue-generator/package.json index 386f060..d3ce22c 100644 --- a/packages/vue-generator/package.json +++ b/packages/vue-generator/package.json @@ -26,6 +26,7 @@ "license": "MIT", "homepage": "https://opentiny.design/tiny-engine", "dependencies": { + "@opentiny/tiny-engine-controller": "workspace:*", "@opentiny/tiny-engine-builtin-component": "workspace:*", "@vue/compiler-sfc": "3.2.45", "@vue/shared": "^3.3.4", diff --git a/packages/vue-generator/src/utils/index.js b/packages/vue-generator/src/utils/index.js index e39e9f1..d9e7b1b 100644 --- a/packages/vue-generator/src/utils/index.js +++ b/packages/vue-generator/src/utils/index.js @@ -13,6 +13,7 @@ import { capitalize, hyphenate } from '@vue/shared' import { tinyIcon as unifyIconName } from '../pre-processor' import { TINY_ICON, JS_FUNCTION } from '../constant' +import prettierConfig from '@opentiny/tiny-engine-controller/js/config-files/prettierrc' const getTypeOfSchema = (schema) => schema.componentName @@ -69,12 +70,7 @@ const lowerFirst = (str) => str[0].toLowerCase() + str.slice(1) */ const toPascalCase = (input, delimiter = '-') => input.split(delimiter).map(capitalize).join('') -const commonOpts = { - printWidth: 120, - semi: false, - singleQuote: true, - trailingComma: 'none' -} +const commonOpts = prettierConfig const prettierOpts = { vue: { ...commonOpts, parser: 'vue', htmlWhitespaceSensitivity: 'ignore' }, js: { ...commonOpts, parser: 'typescript' } diff --git a/packages/vue-generator/vite.config.js b/packages/vue-generator/vite.config.js index 69ea635..96ac13f 100644 --- a/packages/vue-generator/vite.config.js +++ b/packages/vue-generator/vite.config.js @@ -1,14 +1,14 @@ /** -* Copyright (c) 2023 - present TinyEngine Authors. -* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd. -* -* Use of this source code is governed by an MIT-style license. -* -* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, -* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR -* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. -* -*/ + * Copyright (c) 2023 - present TinyEngine Authors. + * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd. + * + * Use of this source code is governed by an MIT-style license. + * + * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, + * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR + * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. + * + */ import { defineConfig } from 'vite' import path from 'path'