Update build tools (#2814)

* Update build tools (babel, eslint and webpack)

* Fix karma configuration (unit tests)

* Fix invalid glob path on Windows

* Fix codemirror editor modes location for development

* Break welcome text on smaller terminals

* Fix ESLint error and reduce PlantUML compression level
This commit is contained in:
Felix Häusler 2022-01-02 11:48:38 +01:00 committed by GitHub
parent 16d61572e8
commit 1cc2d4e3ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
47 changed files with 2265 additions and 3725 deletions

View File

@ -8,7 +8,7 @@ const chalk = require('chalk')
const del = require('del')
const fs = require('fs-extra')
const webpack = require('webpack')
const Multispinner = require('multispinner')
const Listr = require('listr')
const mainConfig = require('./webpack.main.config')
@ -39,40 +39,53 @@ async function build () {
const to = path.resolve(__dirname, '../static/themes')
await fs.copy(from, to)
const tasks = ['main', 'renderer']
const m = new Multispinner(tasks, {
preText: 'building',
postText: 'process'
})
let results = ''
m.on('success', () => {
process.stdout.write('\x1B[2J\x1B[0f')
console.log(`\n\n${results}`)
console.log(`${okayLog}take it away ${chalk.yellow('`electron-builder`')}\n`)
process.exit()
})
const tasks = new Listr(
[
{
title: 'building main process',
task: async () => {
await pack(mainConfig)
.then(result => {
results += result + '\n\n'
})
.catch(err => {
console.log(`\n ${errorLog}failed to build main process`)
console.error(`\n${err}\n`)
process.exit(1)
})
}
},
{
title: 'building renderer process',
task: async () => {
await pack(rendererConfig)
.then(result => {
results += result + '\n\n'
})
.catch(err => {
console.log(`\n ${errorLog}failed to build renderer process`)
console.error(`\n${err}\n`)
process.exit(1)
})
}
}
],
{ concurrent: 2 }
)
pack(mainConfig).then(result => {
results += result + '\n\n'
m.success('main')
}).catch(err => {
m.error('main')
console.log(`\n ${errorLog}failed to build main process`)
console.error(`\n${err}\n`)
process.exit(1)
})
pack(rendererConfig).then(result => {
results += result + '\n\n'
m.success('renderer')
}).catch(err => {
m.error('renderer')
console.log(`\n ${errorLog}failed to build renderer process`)
console.error(`\n${err}\n`)
process.exit(1)
})
await tasks
.run()
.then(() => {
process.stdout.write('\x1B[2J\x1B[0f')
console.log(`\n\n${results}`)
console.log(`${okayLog}take it away ${chalk.yellow('`electron-builder`')}\n`)
process.exit()
})
.catch(err => {
process.exit(1)
})
}
function pack (config) {
@ -106,8 +119,8 @@ function greeting () {
const cols = process.stdout.columns
let text = ''
if (cols > 85) text = 'lets-build'
else if (cols > 60) text = 'lets-|build'
if (cols > 155) text = 'building marktext'
else if (cols > 76) text = 'building|marktext'
else text = false
if (text && !isCI) {
@ -117,6 +130,6 @@ function greeting () {
space: false
})
} else {
console.log(chalk.yellow.bold('\n lets-build'))
console.log(chalk.yellow.bold('\n building marktext'))
}
}

View File

@ -1,4 +1,4 @@
const hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
const hotClient = require('webpack-hot-middleware/client?reload=true')
hotClient.subscribe(event => {
/**

View File

@ -51,7 +51,7 @@ function startRenderer () {
compiler.hooks.compilation.tap('HtmlWebpackPluginAfterEmit', compilation => {
HtmlWebpackPlugin.getHooks(compilation).afterEmit.tapAsync(
'AfterPlugin', // <-- Set a meaningful name here for stacktraces
'AfterPlugin',
(data, cb) => {
hotMiddleware.publish({ action: 'reload' })
// Tell webpack to move on
@ -64,21 +64,28 @@ function startRenderer () {
logStats('Renderer', stats)
})
const server = new WebpackDevServer(
compiler,
{
contentBase: path.join(__dirname, '../'),
quiet: true,
setup (app, ctx) {
app.use(hotMiddleware)
ctx.middleware.waitUntilValid(() => {
resolve()
})
const server = new WebpackDevServer({
host: '127.0.0.1',
port: 9091,
hot: true,
liveReload: true,
compress: true,
static: [
{
directory: path.join(__dirname, '../node_modules/codemirror/mode'),
publicPath: '/codemirror/mode',
watch: false
}
],
onBeforeSetupMiddleware ({ app, middleware}) {
app.use(hotMiddleware)
middleware.waitUntilValid(() => {
resolve()
})
}
)
}, compiler)
server.listen(9091)
server.start()
})
}
@ -159,7 +166,7 @@ function greeting () {
const cols = process.stdout.columns
let text = ''
if (cols > 104) text = 'building marktext'
if (cols > 155) text = 'building marktext'
else if (cols > 76) text = 'building|marktext'
else text = false

View File

@ -1,4 +1,4 @@
const GitRevisionPlugin = require('git-revision-webpack-plugin')
const { GitRevisionPlugin } = require('git-revision-webpack-plugin')
const { version } = require('../package.json')
const getEnvironmentDefinitions = function () {

View File

@ -3,14 +3,21 @@
process.env.BABEL_ENV = 'main'
const path = require('path')
const webpack = require('webpack')
const ESLintPlugin = require('eslint-webpack-plugin')
const { getEnvironmentDefinitions } = require('./marktextEnvironment')
const { dependencies } = require('../package.json')
const webpack = require('webpack')
const proMode = process.env.NODE_ENV === 'production'
const isProduction = process.env.NODE_ENV === 'production'
/** @type {import('webpack').Configuration} */
const mainConfig = {
mode: 'development',
devtool: '#cheap-module-eval-source-map',
devtool: 'eval-cheap-module-source-map',
optimization: {
emitOnErrors: false
},
entry: {
main: path.join(__dirname, '../src/main/index.js')
},
@ -19,18 +26,6 @@ const mainConfig = {
],
module: {
rules: [
{
test: /\.(js)$/,
enforce: 'pre',
exclude: /node_modules/,
use: {
loader: 'eslint-loader',
options: {
formatter: require('eslint-friendly-formatter'),
failOnError: true
}
}
},
{
test: /\.js$/,
use: 'babel-loader',
@ -46,16 +41,33 @@ const mainConfig = {
]
},
node: {
__dirname: !proMode,
__filename: !proMode
__dirname: !isProduction,
__filename: !isProduction
},
cache: false,
output: {
filename: '[name].js',
libraryTarget: 'commonjs2',
path: path.join(__dirname, '../dist/electron')
},
plugins: [
new webpack.NoEmitOnErrorsPlugin(),
new ESLintPlugin({
extensions: ['js'],
files: [
'src',
'test'
],
exclude: [
'node_modules'
],
emitError: true,
failOnError: true,
// NB: Threads must be disabled, otherwise no errors are emitted.
threads: false,
formatter: require('eslint-friendly-formatter'),
context: path.resolve(__dirname, '../'),
overrideConfigFile: '.eslintrc.js'
}),
// Add global environment definitions.
new webpack.DefinePlugin(getEnvironmentDefinitions())
],
@ -69,14 +81,18 @@ const mainConfig = {
}
// Fix debugger breakpoints
if (!proMode && process.env.MARKTEXT_BUILD_VSCODE_DEBUG) {
mainConfig.devtool = '#inline-source-map'
if (!isProduction && process.env.MARKTEXT_BUILD_VSCODE_DEBUG) {
mainConfig.devtool = 'inline-source-map'
}
/**
* Adjust mainConfig for development settings
*/
if (!proMode) {
if (!isProduction) {
mainConfig.cache = {
name: 'main-dev',
type: 'filesystem'
}
mainConfig.plugins.push(
new webpack.DefinePlugin({
'__static': `"${path.join(__dirname, '../static').replace(/\\/g, '\\\\')}"`
@ -87,9 +103,10 @@ if (!proMode) {
/**
* Adjust mainConfig for production settings
*/
if (proMode) {
mainConfig.devtool = '#nosources-source-map'
if (isProduction) {
mainConfig.devtool = 'nosources-source-map'
mainConfig.mode = 'production'
mainConfig.optimization.minimize = true
}
module.exports = mainConfig

View File

@ -11,10 +11,12 @@ const VueLoaderPlugin = require('vue-loader/lib/plugin')
const SpritePlugin = require('svg-sprite-loader/plugin')
const postcssPresetEnv = require('postcss-preset-env')
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
const ESLintPlugin = require('eslint-webpack-plugin')
const { getRendererEnvironmentDefinitions } = require('./marktextEnvironment')
const { dependencies } = require('../package.json')
const proMode = process.env.NODE_ENV === 'production'
const isProduction = process.env.NODE_ENV === 'production'
/**
* List of node_modules to include in webpack bundle
* Required for specific packages like Vue UI libraries
@ -23,9 +25,16 @@ const proMode = process.env.NODE_ENV === 'production'
*/
const whiteListedModules = ['vue']
/** @type {import('webpack').Configuration} */
const rendererConfig = {
mode: 'development',
devtool: '#cheap-module-eval-source-map',
devtool: 'eval-cheap-module-source-map',
optimization: {
emitOnErrors: false
},
infrastructureLogging: {
level: 'warn',
},
entry: {
renderer: path.join(__dirname, '../src/renderer/main.js')
},
@ -36,17 +45,14 @@ const rendererConfig = {
rules: [
{
test: require.resolve(path.join(__dirname, '../src/muya/lib/assets/libs/snap.svg-min.js')),
use: 'imports-loader?this=>window,fix=>module.exports=0',
use: 'imports-loader?this=>window,fix=>module.exports=0'
},
{
test: /\.(js|vue)$/,
enforce: 'pre',
exclude: /node_modules/,
test: /\.vue$/,
use: {
loader: 'eslint-loader',
loader: 'vue-loader',
options: {
formatter: require('eslint-friendly-formatter'),
failOnError: true
sourceMap: true
}
}
},
@ -61,16 +67,21 @@ const rendererConfig = {
test: /\.css$/,
exclude: /(theme\-chalk(?:\/|\\)index|exportStyle|katex|github\-markdown|prism[\-a-z]*|\.theme|headerFooterStyle)\.css$/,
use: [
proMode ? MiniCssExtractPlugin.loader : 'style-loader',
{ loader: 'css-loader', options: { importLoaders: 1 } },
{ loader: 'postcss-loader', options: {
ident: 'postcss',
plugins: () => [
postcssPresetEnv({
stage: 0
})
]
} }
isProduction ? MiniCssExtractPlugin.loader : 'style-loader',
{
loader: 'css-loader',
options: { importLoaders: 1 }
},
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
postcssPresetEnv({ stage: 0 })
],
},
}
}
]
},
{
@ -96,15 +107,6 @@ const rendererConfig = {
name: '[name].[ext]'
}
},
{
test: /\.vue$/,
use: {
loader: 'vue-loader',
options: {
sourceMap: true
}
}
},
{
test: /\.svg$/,
use: [
@ -120,45 +122,54 @@ const rendererConfig = {
},
{
test: /\.(png|jpe?g|gif)(\?.*)?$/,
use: {
loader: 'url-loader',
query: {
limit: 10000,
name: 'imgs/[name]--[folder].[ext]'
}
type: 'asset',
generator: {
filename: 'images/[name].[contenthash:8][ext]'
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: 'media/[name]--[folder].[ext]'
type: 'asset/resource',
generator: {
filename: 'media/[name].[contenthash:8][ext]'
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
use: {
loader: 'url-loader',
query: {
limit: 100000,
name: 'fonts/[name]--[folder].[ext]'
}
type: 'asset/resource',
generator: {
filename: 'fonts/[name].[contenthash:8][ext]'
}
},
{
test: /\.md$/,
use: [
'raw-loader'
]
type: 'asset/source'
}
]
},
node: {
__dirname: !proMode,
__filename: !proMode
__dirname: !isProduction,
__filename: !isProduction
},
plugins: [
new ESLintPlugin({
cache: !isProduction,
extensions: ['js', 'vue'],
files: [
'src',
'test'
],
exclude: [
'node_modules'
],
emitError: true,
failOnError: true,
// NB: Threads must be disabled, otherwise no errors are emitted.
threads: false,
formatter: require('eslint-friendly-formatter'),
context: path.resolve(__dirname, '../'),
overrideConfigFile: '.eslintrc.js'
}),
new SpritePlugin(),
new HtmlWebpackPlugin({
filename: 'index.html',
@ -166,13 +177,16 @@ const rendererConfig = {
minify: {
collapseWhitespace: true,
removeAttributeQuotes: true,
removeComments: true
removeComments: true,
minifyJS: true,
minifyCSS: true
},
nodeModules: process.env.NODE_ENV !== 'production'
isBrowser: false,
isDevelopment: !isProduction,
nodeModules: !isProduction
? path.resolve(__dirname, '../node_modules')
: false
}),
new webpack.NoEmitOnErrorsPlugin(),
new webpack.DefinePlugin(getRendererEnvironmentDefinitions()),
// Use node http request instead axios's XHR adapter.
new webpack.NormalModuleReplacementPlugin(
@ -181,10 +195,13 @@ const rendererConfig = {
),
new VueLoaderPlugin()
],
cache: false,
output: {
filename: '[name].js',
libraryTarget: 'commonjs2',
path: path.join(__dirname, '../dist/electron')
path: path.join(__dirname, '../dist/electron'),
assetModuleFilename: 'assets/[name].[contenthash:8][ext]',
asyncChunks: true
},
resolve: {
alias: {
@ -203,12 +220,17 @@ const rendererConfig = {
/**
* Adjust rendererConfig for development settings
*/
if (!proMode) {
if (!isProduction) {
rendererConfig.cache = { type: 'memory' }
// NOTE: Caching between builds is currently not possible because all SVGs are invalid on second build due to svgo-loader.
// rendererConfig.cache = {
// name: 'renderer-dev',
// type: 'filesystem'
// }
rendererConfig.plugins.push(
new webpack.DefinePlugin({
'__static': `"${path.join(__dirname, '../static').replace(/\\/g, '\\\\')}"`
}),
new webpack.HotModuleReplacementPlugin()
})
)
}
@ -220,16 +242,18 @@ if (process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 'test' &&
}
// Fix debugger breakpoints
if (!proMode && process.env.MARKTEXT_BUILD_VSCODE_DEBUG) {
rendererConfig.devtool = '#inline-source-map'
if (!isProduction && process.env.MARKTEXT_BUILD_VSCODE_DEBUG) {
rendererConfig.devtool = 'inline-source-map'
}
/**
* Adjust rendererConfig for production settings
*/
if (proMode) {
rendererConfig.devtool = '#nosources-source-map'
if (isProduction) {
rendererConfig.devtool = 'nosources-source-map'
rendererConfig.mode = 'production'
rendererConfig.optimization.minimize = true
rendererConfig.plugins.push(
new webpack.DefinePlugin({
'process.env.UNSPLASH_ACCESS_KEY': JSON.stringify(process.env.UNSPLASH_ACCESS_KEY)
@ -237,22 +261,23 @@ if (proMode) {
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: '[name].[hash].css',
chunkFilename: '[id].[hash].css'
filename: '[name].[contenthash].css',
chunkFilename: '[id].[contenthash].css'
}),
new CopyWebpackPlugin([
{
from: path.join(__dirname, '../static'),
to: path.join(__dirname, '../dist/electron/static'),
ignore: ['.*']
},
{
from: path.resolve(__dirname, '../node_modules/codemirror/mode/*/*'),
to: path.join(__dirname, '../dist/electron/codemirror/mode/[name]/[name].js')
}
]),
new webpack.LoaderOptionsPlugin({
minimize: true
new CopyWebpackPlugin({
patterns: [
{
from: path.join(__dirname, '../static'),
to: path.join(__dirname, '../dist/electron/static'),
globOptions: {
ignore: ['.*']
}
},
{
from: path.resolve(__dirname, '../node_modules/codemirror/mode/*/*').replace(/\\/g, '/'),
to: path.join(__dirname, '../dist/electron/codemirror/mode/[name]/[name][ext]')
}
]
})
)
}

View File

@ -1,7 +1,7 @@
module.exports = {
root: true,
parserOptions: {
parser: 'babel-eslint',
parser: '@babel/eslint-parser',
ecmaVersion: 8,
ecmaFeatures: {
impliedStrict: true
@ -64,5 +64,10 @@ module.exports = {
extensions: ['.js', '.vue', '.json', '.css', '.node']
}
}
}
},
ignorePatterns: [
'node_modules',
'src/muya/dist/**/*',
'src/muya/webpack.config.js'
]
}

1
.gitignore vendored
View File

@ -14,3 +14,4 @@ thumbs.db
!.gitkeep
.idea
.env
.eslintcache

View File

@ -12,13 +12,13 @@ const presetsHash = {
test: [
[presetEnv,
{
targets: { 'node': 10 }
targets: { 'node': 16 }
}]
],
main: [
[presetEnv,
{
targets: { 'node': 10 }
targets: { 'node': 16 }
}]
],
renderer: [
@ -27,7 +27,7 @@ const presetsHash = {
useBuiltIns: false,
targets: {
electron: require('electron/package.json').version,
node: 10
node: 16
}
}]
]
@ -46,8 +46,7 @@ module.exports = function (api) {
style: false,
libraryName: 'element-ui'
}
]
)
])
}
return {

View File

@ -14,6 +14,7 @@ files:
- "!node_modules/dagre-d3-renderer/dist/demo/"
- "!node_modules/dragula/resources"
- "!node_modules/**/*.js.map"
- "!node_modules/**/*.cjs.map"
- "!node_modules/**/*.ts.map"
# Don't bundle build files
- "!node_modules/@felixrieseberg/spellchecker/bin"

View File

@ -19,14 +19,14 @@
"lint": "eslint --ext .js,.vue -f ./node_modules/eslint-friendly-formatter src test",
"lint:fix": "eslint --ext .js,.vue -f ./node_modules/eslint-friendly-formatter --fix src test",
"pack": "yarn run pack:main && yarn run pack:renderer",
"pack:main": "cross-env NODE_ENV=production webpack --progress --colors --config .electron-vue/webpack.main.config.js",
"pack:renderer": "cross-env NODE_ENV=production webpack --progress --colors --config .electron-vue/webpack.renderer.config.js",
"pack:main": "cross-env NODE_ENV=production webpack --progress --config .electron-vue/webpack.main.config.js",
"pack:renderer": "cross-env NODE_ENV=production webpack --progress --config .electron-vue/webpack.renderer.config.js",
"postinstall": "node .electron-vue/postinstall.js && yarn run rebuild && yarn run lint:fix",
"test": "yarn run unit && yarn run e2e",
"test:specs": "node -r esm test/specs/commonMark/run.spec.js && node -r esm test/specs/gfm/run.spec.js",
"unit": "cross-env NODE_ENV=test ELECTRON_DISABLE_SECURITY_WARNINGS=true karma start test/unit/karma.conf.js",
"preinstall": "node .electron-vue/preinstall.js",
"build:muya": "cd src/muya && webpack --progress --colors --config webpack.config.js",
"build:muya": "cd src/muya && webpack --progress --config webpack.config.js",
"release:muya": "yarn run build:muya && cd src/muya && yarn publish",
"rebuild": "electron-rebuild -f",
"gen-third-party": "node tools/generateThirdPartyLicense.js",
@ -39,8 +39,8 @@
"@marktext/file-icons": "^1.0.5",
"@octokit/rest": "^18.12.0",
"arg": "^5.0.1",
"axios": "0.22.0",
"ced": "^1.0.0",
"axios": "^0.24.0",
"ced": "^2.0.0",
"chokidar": "^3.5.2",
"codemirror": "^5.65.0",
"command-exists": "^1.2.9",
@ -62,7 +62,7 @@
"github-markdown-css": "^3.0.1",
"html-tags": "^3.1.0",
"iconv-lite": "^0.6.3",
"iso-639-1": "^2.1.10",
"iso-639-1": "^2.1.11",
"joplin-turndown-plugin-gfm": "^1.0.12",
"katex": "^0.15.1",
"keyboard-layout": "^2.0.17",
@ -89,19 +89,19 @@
"webfontloader": "^1.6.28"
},
"devDependencies": {
"@babel/core": "^7.16.0",
"@babel/plugin-proposal-class-properties": "^7.16.0",
"@babel/plugin-proposal-export-default-from": "^7.16.0",
"@babel/plugin-proposal-function-bind": "^7.16.0",
"@babel/core": "^7.16.5",
"@babel/eslint-parser": "^7.16.5",
"@babel/plugin-proposal-class-properties": "^7.16.5",
"@babel/plugin-proposal-export-default-from": "^7.16.5",
"@babel/plugin-proposal-function-bind": "^7.16.5",
"@babel/plugin-syntax-class-properties": "^7.12.13",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-transform-runtime": "^7.16.4",
"@babel/preset-env": "^7.16.4",
"@babel/register": "^7.16.0",
"@babel/runtime": "^7.16.3",
"@babel/plugin-transform-runtime": "^7.16.5",
"@babel/preset-env": "^7.16.5",
"@babel/register": "^7.16.5",
"@babel/runtime": "^7.16.5",
"@markedjs/html-differ": "^3.0.4",
"@playwright/test": "^1.17.1",
"babel-eslint": "^10.1.0",
"babel-loader": "^8.2.3",
"babel-plugin-component": "^1.1.1",
"babel-plugin-istanbul": "^6.1.1",
@ -109,10 +109,10 @@
"chai": "^4.3.4",
"chalk": "^4.1.2",
"cheerio": "^1.0.0-rc.10",
"copy-webpack-plugin": "^5.1.2",
"copy-webpack-plugin": "^10.2.0",
"cross-env": "^7.0.3",
"css-loader": "^3.6.0",
"del": "^5.1.0",
"css-loader": "^6.5.1",
"del": "^6.0.0",
"devtron": "^1.4.0",
"dotenv": "^10.0.0",
"electron": "^15.3.4",
@ -120,58 +120,60 @@
"electron-devtools-installer": "^3.2.0",
"electron-rebuild": "^3.2.5",
"electron-updater": "^4.6.3",
"eslint": "^7.32.0",
"eslint-config-standard": "^14.1.1",
"eslint": "^8.5.0",
"eslint-config-standard": "^16.0.3",
"eslint-friendly-formatter": "^4.0.1",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-loader": "^4.0.2",
"eslint-plugin-html": "^6.2.0",
"eslint-plugin-import": "^2.25.3",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.3.1",
"eslint-plugin-promise": "^6.0.0",
"eslint-plugin-standard": "^4.1.0",
"eslint-plugin-vue": "^6.2.2",
"eslint-plugin-vue": "^8.2.0",
"eslint-webpack-plugin": "^3.1.1",
"esm": "^3.2.25",
"file-loader": "^6.2.0",
"git-revision-webpack-plugin": "^3.0.6",
"html-webpack-plugin": "^4.5.2",
"git-revision-webpack-plugin": "^5.0.0",
"html-webpack-plugin": "^5.5.0",
"imports-loader": "^0.8.0",
"karma": "^6.3.9",
"karma-chai": "^0.1.0",
"karma-coverage": "^2.0.3",
"karma-coverage": "^2.1.0",
"karma-electron": "^7.1.0",
"karma-mocha": "^2.0.1",
"karma-sourcemap-loader": "^0.3.8",
"karma-spec-reporter": "0.0.32",
"karma-webpack": "^5.0.0",
"license-checker": "^25.0.1",
"listr": "^0.14.3",
"marked": "^1.2.9",
"mini-css-extract-plugin": "^1.6.2",
"mini-css-extract-plugin": "^2.4.5",
"mocha": "^8.4.0",
"multispinner": "^0.2.1",
"node-fetch": "^2.6.6",
"node-loader": "^1.0.3",
"node-loader": "^2.0.0",
"path-browserify": "^1.0.1",
"playwright": "^1.17.1",
"postcss-loader": "^3.0.0",
"postcss-preset-env": "^6.7.0",
"postcss": "^8.4.5",
"postcss-loader": "^6.2.1",
"postcss-preset-env": "^7.1.0",
"raw-loader": "^4.0.2",
"require-dir": "^1.2.0",
"style-loader": "^2.0.0",
"svg-sprite-loader": "^4.3.0",
"svgo": "^1.3.2",
"svgo-loader": "^2.2.2",
"style-loader": "^3.3.1",
"svg-sprite-loader": "^6.0.11",
"svgo": "^2.8.0",
"svgo-loader": "^3.0.0",
"to-string-loader": "^1.2.0",
"url-loader": "^4.1.1",
"vue-html-loader": "^1.2.4",
"vue-loader": "^15.9.8",
"vue-style-loader": "^4.1.3",
"vue-template-compiler": "^2.6.14",
"webpack": "^4.46.0",
"webpack-bundle-analyzer": "^3.9.0",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.3",
"webpack": "^5.65.0",
"webpack-bundle-analyzer": "^4.5.0",
"webpack-cli": "^4.9.1",
"webpack-dev-server": "^4.7.1",
"webpack-hot-middleware": "^2.25.1",
"webpack-merge": "^4.2.2"
"webpack-merge": "^5.8.0"
},
"resolutions": {
"cld": "^2.7.1"

View File

@ -72,7 +72,7 @@
<!-- Vue app -->
<div id="app"></div>
<!-- Loading Page when init App -->
<!-- Loading page on application startup -->
<div id="loading-page">
<div class="spinner">
<div class="double-bounce1 dot"></div>
@ -110,9 +110,11 @@
</script>
<!-- Set `__static` path to static files in production -->
<script>
if (process.env.NODE_ENV !== 'development') window.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
</script>
<% if (!htmlWebpackPlugin.options.isBrowser && !htmlWebpackPlugin.options.isDevelopment) { %>
<script>
window.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
</script>
<% } %>
<!-- webpack builds are automatically injected -->
</body>

View File

@ -208,7 +208,7 @@ class WindowManager extends EventEmitter {
}
const { windows } = this
const result = []
for (var [key, value] of windows) {
for (const [key, value] of windows) {
if (value.type === type) {
result.push({
id: key,

View File

@ -169,8 +169,7 @@ class Watcher {
ignorePermissionErrors: true,
// Just to be sure when a file is replaced with a directory don't watch recursively.
depth: type === 'file'
? (isOsx ? 1 : 0) : undefined,
depth: type === 'file' ? (isOsx ? 1 : 0) : undefined,
// Please see GH#1043
awaitWriteFinish: {

View File

@ -59,7 +59,8 @@ try {
} catch (err) {
// Catch errors that may come from invalid configuration files like settings.
const msgHint = err.message.includes('Config schema violation')
? 'This seems to be an issue with your configuration file(s). ' : ''
? 'This seems to be an issue with your configuration file(s). '
: ''
log.error(`Loading MarkText failed during initialization! ${msgHint}`, err)
const EXIT_ON_ERROR = !!process.env.MARKTEXT_EXIT_ON_ERROR

View File

@ -79,9 +79,11 @@ class BaseWindow extends EventEmitter {
titleBarStyle
} = userPreference.getAll()
/* eslint-disable */
const baseUrl = process.env.NODE_ENV === 'development'
? 'http://localhost:9091'
: `file://${__dirname}/index.html`
/* eslint-enable */
const url = new URL(baseUrl)
url.searchParams.set('udp', paths.userDataPath)

View File

@ -218,10 +218,12 @@ const formatCtrl = ContentState => {
}))
}
neighbors = type ? neighbors.filter(n => {
return n.type === type ||
n.type === 'html_tag' && n.tag === type
}) : neighbors
neighbors = type
? neighbors.filter(n => {
return n.type === type ||
n.type === 'html_tag' && n.tag === type
})
: neighbors
for (const neighbor of neighbors) {
clearFormat(neighbor, { start, end })

View File

@ -678,19 +678,6 @@ const paragraphCtrl = ContentState => {
this.muya.eventCenter.dispatch('stateChange')
}
ContentState.prototype.getPreBlock = function (block) {
const { children } = block
if (!children || !children.length) return null
for (const child of children) {
if (child.type === 'pre') {
return child
} else {
return this.getPreBlock(child)
}
}
return null
}
// make a dulication of the current block
ContentState.prototype.duplicate = function () {
const { start, end } = this.cursor

View File

@ -51,7 +51,7 @@ block.checkbox = /^\[([ xX])\] +/
block.bullet = /(?:[*+-]|\d{1,9}(?:\.|\)))/ // patched: support "(" as ordered list delimiter too
// patched: fix https://github.com/marktext/marktext/issues/831#issuecomment-477719256
// block.item = /^( *)(bull) ?[^\n]*(?:\n(?!\1bull ?)[^\n]*)*/
block.item = /^(( {0,3})(bull) [^\n]*(?:\n(?!(\2bull |\2bull\n))[^\n]*)*|( {0,3})(bull)(?:\n(?!(\2bull |\2bull\n)))*)/
block.item = /^(( {0,3})(bull) [^\n]*(?:\n(?!(\2bull |\2bull\n))[^\n]*)*|( {0,3})(bull)(?:\n(?!(\2bull |\2bull\n)))*)/ // eslint-disable-line no-useless-backreference
block.item = edit(block.item, 'gm')
.replace(/bull/g, block.bullet)
.getRegex()

View File

@ -232,7 +232,7 @@ Lexer.prototype.token = function (src, top) {
let text = cap[2] ? cap[2].trim() : ''
if (text.endsWith('#')) {
var trimmed = rtrim(text, '#')
let trimmed = rtrim(text, '#')
if (this.options.pedantic) {
text = trimmed.trim()
@ -424,7 +424,8 @@ Lexer.prototype.token = function (src, top) {
// Backpedal if it does not belong in this list.
if (i !== l - 1) {
b = this.rules.bullet.exec(cap[i + 1])[0]
if (bull.length > 1 ? b.length === 1
if (bull.length > 1
? b.length === 1
: (b.length > 1 || (this.options.smartLists && b !== bull))) {
src = cap.slice(i + 1).join('\n') + src
i = l - 1

View File

@ -10,7 +10,8 @@ export default function htmlRuby (h, cursor, block, token, outerClass) {
const previewSelector = `span.${CLASS_OR_ID.AG_RUBY_RENDER}`
return children ? [
return children
? [
h(`span.${className}.${CLASS_OR_ID.AG_RUBY}`, [
h(`span.${CLASS_OR_ID.AG_INLINE_RULE}.${CLASS_OR_ID.AG_RUBY_TEXT}`, content),
h(previewSelector, {
@ -21,7 +22,8 @@ export default function htmlRuby (h, cursor, block, token, outerClass) {
}, vNode)
])
// if children is empty string, no need to render ruby charactors...
] : [
]
: [
h(`span.${className}.${CLASS_OR_ID.AG_RUBY}`, [
h(`span.${CLASS_OR_ID.AG_INLINE_RULE}.${CLASS_OR_ID.AG_RUBY_TEXT}`, content)
])

View File

@ -1,8 +1,8 @@
// ASCII PUNCTUATION character
// export const punctuation = ['!', '"', '#', '$', '%', '&', "'", '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~']
/* eslint-disable no-useless-escape */
/* eslint-disable no-useless-escape, prefer-regex-literals */
export const PUNCTUATION_REG = new RegExp(/[!"#$%&'()*+,\-./:;<=>?@\[\]^_`{|}~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u0AF0\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E42\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC9\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD805[\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDF3C-\uDF3E]|\uD809[\uDC70-\uDC74]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]/)
/* eslint-enable no-useless-escape */
/* eslint-enable no-useless-escape, prefer-regex-literals */
// selected from https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes
export const WHITELIST_ATTRIBUTES = Object.freeze([
'align', 'alt', 'checked', 'class', 'color', 'dir', 'disabled', 'for', 'height', 'hidden',

View File

@ -7,56 +7,56 @@
font-style: normal;
font-weight: 300;
src: local('Open Sans Light'), local('OpenSans-Light'),
url('./fonts/open-sans-v15-latin_latin-ext-300.woff') format('woff');
url('./fonts/open-sans-v27-latin-ext_latin-300.woff') format('woff');
}
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 300;
src: local('Open Sans Light Italic'), local('OpenSans-LightItalic'),
url('./fonts/open-sans-v15-latin_latin-ext-300italic.woff') format('woff');
url('./fonts/open-sans-v27-latin-ext_latin-300italic.woff') format('woff');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 400;
src: local('Open Sans Regular'), local('OpenSans-Regular'),
url('./fonts/open-sans-v15-latin_latin-ext-regular.woff') format('woff');
url('./fonts/open-sans-v27-latin-ext_latin-regular.woff') format('woff');
}
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 400;
src: local('Open Sans Italic'), local('OpenSans-Italic'),
url('./fonts/open-sans-v15-latin_latin-ext-italic.woff') format('woff');
url('./fonts/open-sans-v27-latin-ext_latin-italic.woff') format('woff');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 600;
src: local('Open Sans SemiBold'), local('OpenSans-SemiBold'),
url('./fonts/open-sans-v15-latin_latin-ext-600.woff') format('woff');
url('./fonts/open-sans-v27-latin-ext_latin-600.woff') format('woff');
}
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 600;
src: local('Open Sans SemiBold Italic'), local('OpenSans-SemiBoldItalic'),
url('./fonts/open-sans-v15-latin_latin-ext-600italic.woff') format('woff');
url('./fonts/open-sans-v27-latin-ext_latin-600italic.woff') format('woff');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 700;
src: local('Open Sans Bold'), local('OpenSans-Bold'),
url('./fonts/open-sans-v15-latin_latin-ext-700.woff') format('woff');
url('./fonts/open-sans-v27-latin-ext_latin-700.woff') format('woff');
}
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 700;
src: local('Open Sans Bold Italic'), local('OpenSans-BoldItalic'),
url('./fonts/open-sans-v15-latin_latin-ext-700italic.woff') format('woff');
url('./fonts/open-sans-v27-latin-ext_latin-700italic.woff') format('woff');
}
/*

View File

@ -4,29 +4,46 @@ process.env.BABEL_ENV = 'renderer'
const path = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const postcssPresetEnv = require('postcss-preset-env')
/** @type {import('webpack').Configuration} */
module.exports = {
mode: 'development',
devtool: '',
mode: 'production',
devtool: 'hidden-nosources-source-map',
optimization: {
emitOnErrors: false,
minimize: true
},
entry: {
renderer: path.join(__dirname, './lib/index.js')
},
module: {
rules: [
{
test: require.resolve(path.join(__dirname, './lib/assets/libs/snap.svg-min.js')),
use: 'imports-loader?this=>window,fix=>module.exports=0'
},
{
test: /(theme\-chalk(?:\/|\\)index|exportStyle|katex|github\-markdown|prism[\-a-z]*|\.theme|headerFooterStyle)\.css$/,
use: [
'to-string-loader',
'css-loader'
]
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
{ loader: 'css-loader', options: { importLoader: 1 } },
{
loader: 'css-loader',
options: { importLoaders: 1 }
},
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
['postcss-preset-env',
{
stage: 0
}]
postcssPresetEnv({ stage: 0 })
]
}
}
@ -44,30 +61,23 @@ module.exports = {
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
use: {
loader: 'url-loader',
query: {
limit: 10000,
name: 'imgs/[name]--[folder].[ext]'
}
type: 'asset',
generator: {
filename: 'images/[name].[contenthash:8][ext]'
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: 'media/[name]--[folder].[ext]'
type: 'asset/resource',
generator: {
filename: 'media/[name].[contenthash:8][ext]'
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
use: {
loader: 'url-loader',
query: {
limit: 10000,
name: 'fonts/[name]--[folder].[ext]'
}
type: 'asset/resource',
generator: {
filename: 'fonts/[name].[contenthash:8][ext]'
}
}
]
@ -86,6 +96,13 @@ module.exports = {
path: path.join(__dirname, './dist')
},
resolve: {
extensions: ['.js', '.vue', '.json', '.css', '.node']
alias: {
snapsvg: path.join(__dirname, './lib/assets/libs/snap.svg-min.js')
},
extensions: ['.js', '.vue', '.json', '.css', '.node'],
fallback: {
fs: false,
path: require.resolve('path-browserify')
}
}
}

View File

@ -19,9 +19,7 @@ multiplexMode(codeMirror)
window.CodeMirror = codeMirror
const modes = codeMirror.modeInfo
codeMirror.modeURL = process.env.NODE_ENV !== 'production'
? './node_modules/codemirror/mode/%N/%N.js'
: './codemirror/mode/%N/%N.js'
codeMirror.modeURL = './codemirror/mode/%N/%N.js'
const getModeFromName = name => {
let result = null

View File

@ -54,8 +54,8 @@ export default {
},
methods: {
querySearch (queryString, cb) {
var restaurants = this.restaurants
var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants
const restaurants = this.restaurants
const results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants
// call callback return this results
cb(results)
},

View File

@ -200,7 +200,7 @@ export default {
const index = dicts.findIndex(d => d === spellcheckerLanguage)
if (index === -1 && dicts.length >= 1) {
// Language is not supported, prefer OS language.
var lang = process.env.LANG
let lang = process.env.LANG
lang = lang ? lang.split('.')[0] : null
if (lang) {
lang = lang.replace(/_/g, '-')

View File

@ -3,7 +3,7 @@ import crypto from 'crypto'
import { clipboard } from 'electron'
import fs from 'fs-extra'
import dayjs from 'dayjs'
import Octokit from '@octokit/rest'
import { Octokit } from '@octokit/rest'
import { ensureDirSync } from 'common/filesystem'
import { isImageFile } from 'common/filesystem/paths'
import { isWindows, dataURItoBlob } from './index'
@ -145,7 +145,7 @@ export const uploadImage = async (pathname, image, preferences) => {
})
const path = dayjs().format('YYYY/MM') + `/${dayjs().format('DD-HH-mm-ss')}-${filename}`
const message = `Upload by MarkText at ${dayjs().format('YYYY-MM-DD HH:mm:ss')}`
var payload = {
const payload = {
owner,
repo,
path,

View File

@ -9,9 +9,9 @@ const patchTheme = css => {
}
const getEmojiPickerPatch = () => {
return isLinux ? `.ag-emoji-picker section .emoji-wrapper .item span {
font-family: sans-serif, "Noto Color Emoji";
}` : ''
return isLinux
? '.ag-emoji-picker section .emoji-wrapper .item span { font-family: sans-serif, "Noto Color Emoji"; }'
: ''
}
const getThemeCluster = themeColor => {

View File

@ -2,7 +2,7 @@
const fs = require('fs')
const path = require('path')
const merge = require('webpack-merge')
const { merge } = require('webpack-merge')
const webpack = require('webpack')
const baseConfig = require('../../.electron-vue/webpack.renderer.config')
@ -20,10 +20,14 @@ try {
}
let webpackConfig = merge(baseConfig, {
devtool: '#inline-source-map',
devtool: 'inline-source-map',
cache: false,
output: {
publicPath: '/'
},
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': '"testing"'
'process.env.NODE_ENV': '"development"'
})
]
})

5357
yarn.lock

File diff suppressed because it is too large Load Diff