Skip to content

Commit

Permalink
✨ 支持eslint
Browse files Browse the repository at this point in the history
  • Loading branch information
CodFrm committed Nov 8, 2022
1 parent e3a04db commit e55d23f
Show file tree
Hide file tree
Showing 11 changed files with 1,849 additions and 30 deletions.
1,664 changes: 1,650 additions & 14 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"@types/chrome": "^0.0.193",
"@types/cron": "^2.0.0",
"@types/crypto-js": "^4.1.1",
"@types/eslint": "^8.4.10",
"@types/jest": "^28.1.6",
"@types/pako": "^2.0.0",
"@types/react": "^18.0.15",
Expand Down Expand Up @@ -77,6 +78,7 @@
"jest-environment-jsdom": "^29.1.2",
"mock-xmlhttprequest": "^8.1.0",
"monaco-editor-locales-plugin": "^0.0.3",
"node-polyfill-webpack-plugin": "^2.0.1",
"prettier": "^2.7.1",
"progress-bar-webpack-plugin": "^2.1.0",
"raw-loader": "^4.0.2",
Expand Down
2 changes: 1 addition & 1 deletion src/app/service/synchronize/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ export default class SynchronizeManager extends Manager {
const newScript = await prepareScriptByCode(
code,
script?.downloadUrl || metaObj.downloadUrl || "",
script?.uuid || metaObj.uuid || undefined
script?.uuid || metaObj.uuid
);
newScript.origin = newScript.origin || metaObj.origin;
this.scriptManager.event.upsertHandler(newScript, "sync");
Expand Down
113 changes: 113 additions & 0 deletions src/linter.worker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/* eslint-disable no-restricted-globals */
// @ts-ignore
// eslint-disable-next-line import/no-extraneous-dependencies
import { Linter } from "eslint/lib/linter/linter.js";

// eslint语法检查,使用webworker

const linter = new Linter();

const rules = linter.getRules();

const rule = {
parserOptions: {
ecmaVersion: "latest",
sourceType: "script",
ecmaFeatures: {},
},
rules: {
"constructor-super": ["error"],
"for-direction": ["error"],
"getter-return": ["error"],
"no-async-promise-executor": ["error"],
"no-case-declarations": ["error"],
"no-class-assign": ["error"],
"no-compare-neg-zero": ["error"],
"no-cond-assign": ["error"],
"no-const-assign": ["error"],
"no-constant-condition": ["error"],
"no-control-regex": ["error"],
"no-debugger": ["error"],
"no-delete-var": ["error"],
"no-dupe-args": ["error"],
"no-dupe-class-members": ["error"],
"no-dupe-else-if": ["error"],
"no-dupe-keys": ["error"],
"no-duplicate-case": ["error"],
"no-empty": ["error"],
"no-empty-character-class": ["error"],
"no-empty-pattern": ["error"],
"no-ex-assign": ["error"],
"no-extra-boolean-cast": ["error"],
"no-extra-semi": ["error"],
"no-fallthrough": ["error"],
"no-func-assign": ["error"],
"no-global-assign": ["error"],
"no-import-assign": ["error"],
"no-inner-declarations": ["error"],
"no-invalid-regexp": ["error"],
"no-irregular-whitespace": ["error"],
"no-loss-of-precision": ["error"],
"no-misleading-character-class": ["error"],
"no-mixed-spaces-and-tabs": ["error"],
"no-new-symbol": ["error"],
"no-nonoctal-decimal-escape": ["error"],
"no-obj-calls": ["error"],
"no-octal": ["error"],
"no-prototype-builtins": ["error"],
"no-redeclare": ["error"],
"no-regex-spaces": ["error"],
"no-self-assign": ["error"],
"no-setter-return": ["error"],
"no-shadow-restricted-names": ["error"],
"no-sparse-arrays": ["error"],
"no-this-before-super": ["error"],
"no-undef": ["error"],
"no-unexpected-multiline": ["error"],
"no-unreachable": ["error"],
"no-unsafe-finally": ["error"],
"no-unsafe-negation": ["error"],
"no-unsafe-optional-chaining": ["error"],
"no-unused-labels": ["error"],
"no-unused-vars": ["error"],
"no-useless-backreference": ["error"],
"no-useless-catch": ["error"],
"no-useless-escape": ["error"],
"no-with": ["error"],
"require-yield": ["error"],
"use-isnan": ["error"],
"valid-typeof": ["error"],
},
env: {
es6: true,
browser: true,
greasemonkey: true,
},
};

const severityMap = {
2: 8, // 2 for ESLint is error
1: 4, // 1 for ESLint is warning
};

self.addEventListener("message", (event) => {
const { code, id } = event.data;
const errs = linter.verify(code, rule);
const markers = errs.map((err: any) => ({
code: {
value: err.ruleId,
target: rules.get(err.ruleId).meta.docs.url,
},
startLineNumber: err.line,
endLineNumber: err.endLine,
startColumn: err.column,
endColumn: err.endColumn,
message: err.message,
// 设置错误的等级,此处ESLint与monaco的存在差异,做一层映射
// @ts-ignore
severity: severityMap[err.severity],
source: "ESLint",
}));
// 发回主进程
self.postMessage({ markers, id });
});
41 changes: 40 additions & 1 deletion src/pages/components/CodeEditor/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { LinterWorker } from "@App/pkg/utils/monaco-editor";
import { editor } from "monaco-editor";
import React, { useEffect, useImperativeHandle, useState } from "react";

Expand All @@ -16,7 +17,7 @@ const CodeEditor: React.ForwardRefRenderFunction<
{ editor: editor.ICodeEditor | undefined },
Props
> = ({ id, className, code, diffCode, editable }, ref) => {
const [monacoEditor, setEditor] = useState<any>();
const [monacoEditor, setEditor] = useState<editor.ICodeEditor>();
useImperativeHandle(ref, () => ({
editor: monacoEditor,
}));
Expand Down Expand Up @@ -64,6 +65,7 @@ const CodeEditor: React.ForwardRefRenderFunction<
readOnly: !editable,
});
edit.setValue(code);

setEditor(edit);
}
}, ts);
Expand All @@ -73,6 +75,43 @@ const CodeEditor: React.ForwardRefRenderFunction<
}
};
}, [code, diffCode]);

useEffect(() => {
if (!monacoEditor) {
return () => {};
}
const model = monacoEditor.getModel();
if (!model) {
return () => {};
}
let timer: any;
const lint = () => {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
timer = null;
LinterWorker.sendLinterMessage({
code: model.getValue(),
id,
});
}, 500);
};
// 加载完成就检测一次
lint();
model.onDidChangeContent(() => {
lint();
});
const handler = (message: any) => {
if (id !== message.id) {
return;
}
editor.setModelMarkers(model, "ESLint", message.markers);
};
LinterWorker.hook.addListener("message", handler);
return () => {
LinterWorker.hook.removeListener("message", handler);
};
}, [monacoEditor]);

return (
<div
id={id}
Expand Down
9 changes: 7 additions & 2 deletions src/pages/options/routes/script/ScriptEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ const emptyScript = async (template: string, hotKeys: any, target?: string) => {
}
break;
}
const script = await prepareScriptByCode(code, "", uuidv4());
const script = await prepareScriptByCode(code, "", uuidv4(), true);

return Promise.resolve({
script,
Expand Down Expand Up @@ -155,7 +155,12 @@ function ScriptEditor() {
): Promise<Script> => {
// 解析code生成新的script并更新
return new Promise((resolve) => {
prepareScriptByCode(e.getValue(), script.origin || "", script.uuid)
prepareScriptByCode(
e.getValue(),
script.origin || "",
script.uuid,
!script.id
)
.then((newScript) => {
scriptCtrl.upsert(newScript).then(
() => {
Expand Down
16 changes: 16 additions & 0 deletions src/pkg/utils/monaco-editor.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
// @ts-ignore
// eslint-disable-next-line import/no-unresolved
import dts from "@App/types/scriptcat";
import Hook from "@App/app/service/hook";
import { languages } from "monaco-editor";
import pako from "pako";

// 注册eslint
const linterWorker = new Worker("/src/linter.worker.js");

export default function registerEditor() {
// @ts-ignore
window.tsUrl = "";
Expand Down Expand Up @@ -59,3 +63,15 @@ export default function registerEditor() {
},
});
}

export class LinterWorker {
static hook = new Hook<"message">();

static sendLinterMessage(data: any) {
linterWorker.postMessage(data);
}
}

linterWorker.onmessage = (event) => {
LinterWorker.hook.trigger("message", event.data);
};
27 changes: 15 additions & 12 deletions src/pkg/utils/script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ export function copySubscribe(sub: Subscribe, old: Subscribe): Subscribe {
ret.id = old.id;
ret.createtime = old.createtime;
ret.status = old.status;
ret.error = old.error;
return ret;
}

Expand Down Expand Up @@ -210,7 +209,8 @@ export function strToBase64(str: string): string {
export function prepareScriptByCode(
code: string,
url: string,
uuid?: string
uuid?: string,
newScript?: boolean
): Promise<Script & { oldScript?: Script }> {
const dao = new ScriptDAO();
return new Promise((resolve, reject) => {
Expand Down Expand Up @@ -272,17 +272,19 @@ export function prepareScriptByCode(
};
const handler = async () => {
let old: Script | undefined;
let flag = true;
if (uuid !== undefined) {
old = await dao.findByUUID(uuid);
if (old) {
flag = false;
if (!newScript) {
let flag = true;
if (uuid !== undefined) {
old = await dao.findByUUID(uuid);
if (old) {
flag = false;
}
}
}
if (flag) {
old = await dao.findByNameAndNamespace(script.name, script.namespace);
if (!old) {
old = await dao.findByUUID(script.uuid);
if (flag) {
old = await dao.findByNameAndNamespace(script.name, script.namespace);
if (!old) {
old = await dao.findByUUID(script.uuid);
}
}
}
if (old) {
Expand All @@ -304,6 +306,7 @@ export function prepareScriptByCode(
}
script.checktime = new Date().getTime();
}

resolve(script);
};
handler();
Expand Down
3 changes: 3 additions & 0 deletions webpack.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import CopyPlugin from "copy-webpack-plugin";
import { CleanWebpackPlugin } from "clean-webpack-plugin";
import { presetAttributify, presetUno } from "unocss";

const NodePolyfillPlugin = require("node-polyfill-webpack-plugin");
const UnoCSS = require("@unocss/webpack").default;
const ProgressBarPlugin = require("progress-bar-webpack-plugin");
const MonacoLocalesPlugin = require("monaco-editor-locales-plugin");
Expand Down Expand Up @@ -123,13 +124,15 @@ const config: Configuration = {
UnoCSS({
presets: [presetUno(), presetAttributify()],
}),
new NodePolyfillPlugin(),
],
resolve: {
extensions: [".js", ".ts", ".tsx", ".d.ts", ".tpl"],
alias: {
"@App": path.resolve(__dirname, "src/"),
"@Pkg": path.resolve(__dirname, "pkg/"),
},
mainFields: ["browser", "main", "module"],
},
module: {
rules: [
Expand Down
1 change: 1 addition & 0 deletions webpack.dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ common.entry = {
...common.entry,
content: `${src}/content.ts`,
inject: `${src}/inject.ts`,
"linter.worker": `${src}/linter.worker.ts`,
"editor.worker": "monaco-editor/esm/vs/editor/editor.worker.js",
"ts.worker": "monaco-editor/esm/vs/language/typescript/ts.worker.js",
};
Expand Down
1 change: 1 addition & 0 deletions webpack.no.split.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const dist = `${__dirname}/dist`;
common.entry = {
content: `${src}/content.ts`,
inject: `${src}/inject.ts`,
"linter.worker": `${src}/linter.worker.ts`,
"editor.worker": "monaco-editor/esm/vs/editor/editor.worker.js",
"ts.worker": "monaco-editor/esm/vs/language/typescript/ts.worker.js",
};
Expand Down

0 comments on commit e55d23f

Please sign in to comment.