diff --git a/.gitignore b/.gitignore
index e043bca..47fea0e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,7 +17,6 @@
.env.development.local
.env.test.local
.env.production.local
-.vscode
npm-debug.log*
yarn-debug.log*
diff --git a/.husky/pre-commit b/.husky/pre-commit
new file mode 100644
index 0000000..20d0d06
--- /dev/null
+++ b/.husky/pre-commit
@@ -0,0 +1,4 @@
+#!/bin/sh
+. "$(dirname "$0")/_/husky.sh"
+
+npm run lint
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..eb3d18b
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,5 @@
+{
+ "editor.codeActionsOnSave": {
+ "source.fixAll": true
+ }
+}
diff --git a/jsconfig.json b/jsconfig.json
new file mode 100644
index 0000000..adc4845
--- /dev/null
+++ b/jsconfig.json
@@ -0,0 +1,9 @@
+{
+ "compilerOptions": {
+ "baseUrl": "./",
+ "paths": {
+ "@/*": ["src/*"]
+ }
+ },
+ "exclude": ["node_modules", "dist"]
+}
diff --git a/mm/mm.config.js b/mm/mm.config.js
index 9a15065..57c5e17 100644
--- a/mm/mm.config.js
+++ b/mm/mm.config.js
@@ -10,11 +10,11 @@ const spaceInfo = {
}
/**
- * 配置说明请参考文档:
+ * 配置说明请参考文档:
* https://hongqiye.com/doc/mockm/config/option.html
* @type {import('mockm/@types/config').Config}
*/
-module.exports = util => {
+module.exports = (util) => {
const port = 9000
return {
port,
@@ -29,26 +29,34 @@ module.exports = util => {
})
form.parse(req, async (err, fields = [], files) => {
const file = files.file[0]
- let url = `http://127.0.0.1:${port}/public/upload/${path.parse(file.path).base}`
+ let url = `http://127.0.0.1:${port}/public/upload/${
+ path.parse(file.path).base
+ }`
try {
- url = await dcloud(spaceInfo)({name: file.originalFilename, file: fs.createReadStream(file.path)})
+ url = await dcloud(spaceInfo)({
+ name: file.originalFilename,
+ file: fs.createReadStream(file.path),
+ })
} catch (err) {
// console.log(err)
}
- res.json({url})
+ res.json({ url })
})
},
},
static: [
- { // 测试 netlify 部署
+ {
+ // 测试 netlify 部署
fileDir: `../dist`,
path: `/`,
},
- { // 测试 gitee/github 部署
+ {
+ // 测试 gitee/github 部署
fileDir: `../dist`,
path: `/md`,
},
- { // 访问公共目录
+ {
+ // 访问公共目录
fileDir: `../public`,
path: `/public`,
},
diff --git a/mm/util.js b/mm/util.js
index 476211b..6b9608b 100644
--- a/mm/util.js
+++ b/mm/util.js
@@ -1,19 +1,23 @@
-const fetch = (...args) => import(`node-fetch`).then(({default: fetch}) => fetch(...args))
+const fetch = (...args) =>
+ import(`node-fetch`).then(({ default: fetch }) => fetch(...args))
const FormData = require(`form-data`)
function dcloud(spaceInfo) {
- if(Boolean(spaceInfo.spaceId && spaceInfo.clientSecret) === false) {
+ if (Boolean(spaceInfo.spaceId && spaceInfo.clientSecret) === false) {
throw new Error(`请填写 spaceInfo`)
}
-
+
function sign(data, secret) {
const hmac = require(`crypto`).createHmac(`md5`, secret)
// 排序 obj 再转换为 key=val&key=val 的格式
- const str = Object.keys(data).sort().reduce((acc, cur) => `${acc}&${cur}=${data[cur]}`, ``).slice(1)
+ const str = Object.keys(data)
+ .sort()
+ .reduce((acc, cur) => `${acc}&${cur}=${data[cur]}`, ``)
+ .slice(1)
hmac.update(str)
return hmac.digest(`hex`)
}
-
+
async function anonymousAuthorize() {
const data = {
method: `serverless.auth.user.anonymousAuthorize`,
@@ -29,7 +33,7 @@ function dcloud(spaceInfo) {
method: `POST`,
}).then((res) => res.json())
}
-
+
async function report({ id, token }) {
const reportReq = {
method: `serverless.file.resource.report`,
@@ -47,7 +51,7 @@ function dcloud(spaceInfo) {
method: `POST`,
}).then((res) => res.json())
}
-
+
async function generateProximalSign({ name, token }) {
const data = {
method: `serverless.file.resource.generateProximalSign`,
@@ -66,7 +70,7 @@ function dcloud(spaceInfo) {
}).then((res) => res.json())
return res
}
-
+
async function upload({ data, file }) {
const formdata = new FormData()
Object.entries({
@@ -81,7 +85,7 @@ function dcloud(spaceInfo) {
success_action_status: 200,
file,
}).forEach(([key, val]) => formdata.append(key, val))
-
+
return await fetch(`https://${data.host}`, {
headers: {
'X-OSS-server-side-encrpytion': `AES256`,
@@ -90,7 +94,7 @@ function dcloud(spaceInfo) {
method: `POST`,
})
}
-
+
async function uploadFile({ name = `unnamed.file`, file }) {
const token = (await anonymousAuthorize()).data.accessToken
const res = await generateProximalSign({ name, token })
@@ -99,9 +103,8 @@ function dcloud(spaceInfo) {
const fileUrl = `https://${res.data.cdnDomain}/${res.data.ossPath}`
return fileUrl
}
-
+
return uploadFile
-
}
module.exports = {
diff --git a/package.json b/package.json
index 1ff6527..995ec32 100644
--- a/package.json
+++ b/package.json
@@ -3,6 +3,8 @@
"version": "1.5.7",
"private": false,
"scripts": {
+ "prepare": "husky install",
+ "lint": "vue-cli-service lint src && vue-cli-service lint mm",
"start": "run-p serve mm",
"serve": "vue-cli-service serve",
"build:h5-netlify": "cross-env SERVER_ENV=NETLIFY vue-cli-service build",
@@ -10,6 +12,43 @@
"build-cli": "npm run build && npx shx rm -rf md-cli/dist && npx shx rm -rf dist/**/*.map && npx shx cp -r dist md-cli/ && cd md-cli && npm pack",
"mm": "npx mockm --cwd=mm"
},
+ "eslintConfig": {
+ "root": true,
+ "env": {
+ "node": true
+ },
+ "extends": [
+ "plugin:vue/essential",
+ "eslint:recommended",
+ "@vue/prettier"
+ ],
+ "parserOptions": {
+ "parser": "babel-eslint"
+ },
+ "ignorePatterns": [
+ "src/assets/scripts/renderers"
+ ],
+ "rules": {
+ "prettier/prettier": [
+ "error",
+ {
+ "singleQuote": true,
+ "semi": false
+ }
+ ],
+ "semi": [
+ "error",
+ "never"
+ ],
+ "quotes": [
+ "error",
+ "backtick"
+ ],
+ "no-unused-vars": "off",
+ "no-console": "off",
+ "no-debugger": "off"
+ }
+ },
"dependencies": {
"@vue/shared": "^3.2.26",
"ali-oss": "^6.16.0",
@@ -37,6 +76,15 @@
"vuex": "^3.6.2"
},
"devDependencies": {
+ "@vue/cli-plugin-eslint": "^4.5.12",
+ "@vue/cli-plugin-router": "^4.5.12",
+ "@vue/cli-plugin-vuex": "^4.5.12",
+ "@vue/eslint-config-prettier": "^6.0.0",
+ "babel-eslint": "^10.1.0",
+ "eslint": "^6.8.0",
+ "eslint-plugin-prettier": "^3.4.0",
+ "eslint-plugin-vue": "^6.2.2",
+ "husky": "^7.0.4",
"@vue/cli-plugin-babel": "~4.5.15",
"@vue/cli-service": "~4.5.15",
"async-validator": "^4.0.7",
diff --git a/src/App.vue b/src/App.vue
index 58c415c..eb28b05 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -18,8 +18,8 @@ body,
diff --git a/src/main.js b/src/main.js
index 2e610f6..dd9f989 100644
--- a/src/main.js
+++ b/src/main.js
@@ -1,29 +1,29 @@
-import Vue from "vue";
-import App from "./App";
-import store from "./store";
-import ElementUI from "element-ui";
-import "element-ui/lib/theme-chalk/index.css";
-import "./plugins/element";
-import "codemirror/lib/codemirror.css";
-import "codemirror/theme/xq-light.css";
-import "codemirror/mode/css/css";
-import "codemirror/mode/markdown/markdown";
-import "codemirror/addon/edit/closebrackets";
-import "codemirror/addon/edit/matchbrackets";
-import "codemirror/addon/selection/active-line";
-import "codemirror/addon/hint/show-hint.js";
-import "codemirror/addon/hint/css-hint.js";
-import router from './router';
+import Vue from 'vue'
+import App from './App'
+import store from './store'
+import ElementUI from 'element-ui'
+import 'element-ui/lib/theme-chalk/index.css'
+import './plugins/element'
+import 'codemirror/lib/codemirror.css'
+import 'codemirror/theme/xq-light.css'
+import 'codemirror/mode/css/css'
+import 'codemirror/mode/markdown/markdown'
+import 'codemirror/addon/edit/closebrackets'
+import 'codemirror/addon/edit/matchbrackets'
+import 'codemirror/addon/selection/active-line'
+import 'codemirror/addon/hint/show-hint.js'
+import 'codemirror/addon/hint/css-hint.js'
+import router from './router'
-Vue.use(ElementUI);
+Vue.use(ElementUI)
-Vue.config.productionTip = false;
+Vue.config.productionTip = false
-App.mpType = "app";
+App.mpType = `app`
const app = new Vue({
router,
store,
...App,
-});
-app.$mount("#app");
+})
+app.$mount(`#app`)
diff --git a/src/pages/index/index.vue b/src/pages/index/index.vue
index 4553748..f34e309 100644
--- a/src/pages/index/index.vue
+++ b/src/pages/index/index.vue
@@ -6,10 +6,10 @@
diff --git a/src/plugins/element/index.js b/src/plugins/element/index.js
index 5ebbd87..26e4cda 100644
--- a/src/plugins/element/index.js
+++ b/src/plugins/element/index.js
@@ -1,10 +1,7 @@
-import Vue from "vue";
-import {
- Loading,
- Message,
-} from "element-ui";
+import Vue from 'vue'
+import { Loading, Message } from 'element-ui'
-Vue.component(Message.name, Message);
+Vue.component(Message.name, Message)
-Vue.prototype.$loading = Loading.service;
-Vue.prototype.$message = Message;
+Vue.prototype.$loading = Loading.service
+Vue.prototype.$message = Message
diff --git a/src/router/index.js b/src/router/index.js
index b850506..0545ef9 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -9,7 +9,7 @@ const routes = [
path: `/`,
name: `index`,
component: index,
- }
+ },
]
const router = new VueRouter({
diff --git a/src/store/index.js b/src/store/index.js
index d38456b..4fb6e18 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -1,162 +1,162 @@
-import Vue from "vue";
-import Vuex from "vuex";
-import config from "../assets/scripts/config";
-import WxRenderer from "../assets/scripts/renderers/wx-renderer";
-import { marked } from "marked";
-import CodeMirror from "codemirror/lib/codemirror";
-import DEFAULT_CONTENT from "@/assets/example/markdown.md";
-import DEFAULT_CSS_CONTENT from "@/assets/example/theme-css.txt";
-import { setColor, formatDoc, formatCss } from "../assets/scripts/util";
+import Vue from 'vue'
+import Vuex from 'vuex'
+import config from '../assets/scripts/config'
+import WxRenderer from '../assets/scripts/renderers/wx-renderer'
+import { marked } from 'marked'
+import CodeMirror from 'codemirror/lib/codemirror'
+import DEFAULT_CONTENT from '@/assets/example/markdown.md'
+import DEFAULT_CSS_CONTENT from '@/assets/example/theme-css.txt'
+import { setColor, formatDoc, formatCss } from '../assets/scripts/util'
-Vue.use(Vuex);
+Vue.use(Vuex)
const state = {
wxRenderer: null,
- output: "",
- html: "",
+ output: ``,
+ html: ``,
editor: null,
cssEditor: null,
- currentFont: "",
- currentSize: "",
- currentColor: "",
+ currentFont: ``,
+ currentSize: ``,
+ currentColor: ``,
citeStatus: 0,
nightMode: false,
codeTheme: config.codeThemeOption[0].value,
rightClickMenuVisible: false,
-};
+}
const mutations = {
setEditorValue(state, data) {
- state.editor.setValue(data);
+ state.editor.setValue(data)
},
setCssEditorValue(state, data) {
- state.cssEditor.setValue(data);
+ state.cssEditor.setValue(data)
},
setWxRendererOptions(state, data) {
- state.wxRenderer.setOptions(data);
+ state.wxRenderer.setOptions(data)
},
setCiteStatus(state, data) {
- state.citeStatus = data;
- localStorage.setItem("citeStatus", data);
+ state.citeStatus = data
+ localStorage.setItem(`citeStatus`, data)
},
setCurrentFont(state, data) {
- state.currentFont = data;
- localStorage.setItem("fonts", data);
+ state.currentFont = data
+ localStorage.setItem(`fonts`, data)
},
setCurrentSize(state, data) {
- state.currentSize = data;
- localStorage.setItem("size", data);
+ state.currentSize = data
+ localStorage.setItem(`size`, data)
},
setCurrentColor(state, data) {
- state.currentColor = data;
- localStorage.setItem("color", data);
+ state.currentColor = data
+ localStorage.setItem(`color`, data)
},
setCurrentCodeTheme(state, data) {
- state.codeTheme = data;
- localStorage.setItem("codeTheme", data);
+ state.codeTheme = data
+ localStorage.setItem(`codeTheme`, data)
},
setRightClickMenuVisible(state, data) {
- state.rightClickMenuVisible = data;
+ state.rightClickMenuVisible = data
},
themeChanged(state) {
- state.nightMode = !state.nightMode;
- localStorage.setItem("nightMode", state.nightMode);
+ state.nightMode = !state.nightMode
+ localStorage.setItem(`nightMode`, state.nightMode)
},
initEditorState(state) {
state.currentFont =
- localStorage.getItem("fonts") || config.builtinFonts[0].value;
+ localStorage.getItem(`fonts`) || config.builtinFonts[0].value
state.currentColor =
- localStorage.getItem("color") || config.colorOption[0].value;
+ localStorage.getItem(`color`) || config.colorOption[0].value
state.currentSize =
- localStorage.getItem("size") || config.sizeOption[2].value;
+ localStorage.getItem(`size`) || config.sizeOption[2].value
state.codeTheme =
- localStorage.getItem("codeTheme") || config.codeThemeOption[0].value;
- state.citeStatus = localStorage.getItem("citeStatus") === "true";
- state.nightMode = localStorage.getItem("nightMode") === "true";
+ localStorage.getItem(`codeTheme`) || config.codeThemeOption[0].value
+ state.citeStatus = localStorage.getItem(`citeStatus`) === `true`
+ state.nightMode = localStorage.getItem(`nightMode`) === `true`
state.wxRenderer = new WxRenderer({
theme: setColor(state.currentColor),
fonts: state.currentFont,
size: state.currentSize,
- });
+ })
},
initEditorEntity(state) {
- const editorDom = document.getElementById("editor");
+ const editorDom = document.getElementById(`editor`)
if (!editorDom.value) {
editorDom.value =
- localStorage.getItem("__editor_content") || formatDoc(DEFAULT_CONTENT);
+ localStorage.getItem(`__editor_content`) || formatDoc(DEFAULT_CONTENT)
}
state.editor = CodeMirror.fromTextArea(editorDom, {
- mode: "text/x-markdown",
- theme: "xq-light",
+ mode: `text/x-markdown`,
+ theme: `xq-light`,
lineNumbers: false,
lineWrapping: true,
styleActiveLine: true,
autoCloseBrackets: true,
extraKeys: {
- "Ctrl-F": function autoFormat(editor) {
- const doc = formatDoc(editor.getValue(0));
- localStorage.setItem("__editor_content", doc);
- editor.setValue(doc);
+ 'Ctrl-F': function autoFormat(editor) {
+ const doc = formatDoc(editor.getValue(0))
+ localStorage.setItem(`__editor_content`, doc)
+ editor.setValue(doc)
},
- "Ctrl-S": function save(editor) {},
- "Ctrl-B": function bold(editor) {
- const selected = editor.getSelection();
- editor.replaceSelection(`**${selected}**`);
+ 'Ctrl-S': function save(editor) {},
+ 'Ctrl-B': function bold(editor) {
+ const selected = editor.getSelection()
+ editor.replaceSelection(`**${selected}**`)
},
- "Ctrl-D": function del(editor) {
- const selected = editor.getSelection();
- editor.replaceSelection(`~~${selected}~~`);
+ 'Ctrl-D': function del(editor) {
+ const selected = editor.getSelection()
+ editor.replaceSelection(`~~${selected}~~`)
},
- "Ctrl-I": function italic(editor) {
- const selected = editor.getSelection();
- editor.replaceSelection(`*${selected}*`);
+ 'Ctrl-I': function italic(editor) {
+ const selected = editor.getSelection()
+ editor.replaceSelection(`*${selected}*`)
},
},
- });
+ })
},
initCssEditorEntity(state) {
- const cssEditorDom = document.getElementById("cssEditor");
+ const cssEditorDom = document.getElementById(`cssEditor`)
if (!cssEditorDom.value) {
cssEditorDom.value =
- localStorage.getItem("__css_content") || DEFAULT_CSS_CONTENT;
+ localStorage.getItem(`__css_content`) || DEFAULT_CSS_CONTENT
}
state.cssEditor = CodeMirror.fromTextArea(cssEditorDom, {
- mode: "css",
- theme: "style-mirror",
+ mode: `css`,
+ theme: `style-mirror`,
lineNumbers: false,
lineWrapping: true,
matchBrackets: true,
autofocus: true,
extraKeys: {
- "Ctrl-F": function autoFormat(editor) {
- const doc = formatCss(editor.getValue(0));
- localStorage.setItem("__css_content", doc);
- editor.setValue(doc);
+ 'Ctrl-F': function autoFormat(editor) {
+ const doc = formatCss(editor.getValue(0))
+ localStorage.setItem(`__css_content`, doc)
+ editor.setValue(doc)
},
- "Ctrl-S": function save(editor) {},
+ 'Ctrl-S': function save(editor) {},
},
- });
+ })
},
editorRefresh(state) {
- let renderer = state.wxRenderer.getRenderer(state.citeStatus);
- marked.setOptions({ renderer });
- let output = marked.parse(state.editor.getValue(0));
+ let renderer = state.wxRenderer.getRenderer(state.citeStatus)
+ marked.setOptions({ renderer })
+ let output = marked.parse(state.editor.getValue(0))
// 去除第一行的 margin-top
- output = output.replace(/(style=".*?)"/, '$1;margin-top: 0"');
+ output = output.replace(/(style=".*?)"/, `$1;margin-top: 0"`)
if (state.citeStatus) {
// 引用脚注
- output += state.wxRenderer.buildFootnotes();
+ output += state.wxRenderer.buildFootnotes()
// 附加的一些 style
- output += state.wxRenderer.buildAddition();
+ output += state.wxRenderer.buildAddition()
}
- state.output = output;
+ state.output = output
},
-};
+}
export default new Vuex.Store({
state,
mutations,
actions: {},
-});
+})
diff --git a/vue.config.js b/vue.config.js
index 0335098..6c8db8c 100644
--- a/vue.config.js
+++ b/vue.config.js
@@ -5,9 +5,11 @@ module.exports = {
configureWebpack: (config) => {
config.module.rules.push({
test: /\.(txt|md)$/i,
- use: [{
- loader: 'raw-loader',
- }]
+ use: [
+ {
+ loader: `raw-loader`,
+ },
+ ],
})
},
productionSourceMap: !isProd,