Last active
February 6, 2021 22:22
-
-
Save gustavopch/134513fa7c1f30050e968b5570c26994 to your computer and use it in GitHub Desktop.
ESLint + Svelte + TS (start with this template https://github.com/NicoCevallos/svelte-template which contains an important patch to eslint-plugin-svelte3). Kudos to https://github.com/Sxxov.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { join } = require('path') | |
const eslintSveltePreprocess = require('./eslint-svelte-preprocess') | |
module.exports = { | |
root: true, | |
env: { | |
node: true, | |
browser: true, | |
}, | |
parser: '@typescript-eslint/parser', | |
parserOptions: { | |
createDefaultProgram: true, | |
ecmaVersion: 2019, | |
sourceType: 'module', | |
}, | |
extends: ['eslint:recommended'], | |
plugins: ['svelte3', '@typescript-eslint'], | |
overrides: [ | |
{ | |
files: ['*.svelte'], | |
processor: 'svelte3/svelte3', | |
}, | |
{ | |
files: ['*.ts', '*.json'], | |
extends: ['plugin:@typescript-eslint/recommended'], | |
}, | |
], | |
settings: { | |
'svelte3/preprocess': eslintSveltePreprocess(), | |
}, | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* eslint-disable no-undef */ | |
const esTree = require('@typescript-eslint/typescript-estree') | |
const debugMain = require('debug')('eslint:svelte-preprocess:main') | |
const debugWorker = require('debug')('eslint:svelte-preprocess:worker') | |
const sveltePreprocess = require('svelte-preprocess') | |
const svelteCompiler = require('svelte/compiler') | |
const tty = require('tty') | |
const { | |
SHARE_ENV, | |
Worker, | |
isMainThread, | |
parentPort, | |
workerData, | |
} = require('worker_threads') | |
const mainThread = () => { | |
// Workaround for colored logs in the worker thread | |
if (tty.isatty(process.stderr.fd)) { | |
process.env.DEBUG_COLORS = 'true' | |
} | |
const isRunningWithinCli = !process.argv.includes('--node-ipc') | |
const isDoneBuffer = new SharedArrayBuffer(4) | |
const isDoneView = new Int32Array(isDoneBuffer) | |
const dataBuffer = new SharedArrayBuffer(50 * 1024 * 1024) | |
const dataView = new Uint8Array(dataBuffer) | |
const dataLengthBuffer = new SharedArrayBuffer(4) | |
const dataLengthView = new Uint32Array(dataLengthBuffer) | |
const worker = new Worker(__filename, { | |
env: SHARE_ENV, | |
workerData: [isDoneView, dataView, dataLengthView], | |
}) | |
let lastResult | |
return autoPreprocessConfig => { | |
return (src, filename) => { | |
debugMain(`Asking worker to preprocess ${filename}`) | |
worker.postMessage({ | |
src, | |
filename, | |
autoPreprocessConfig, | |
}) | |
debugMain('Locking thread to wait for worker') | |
const waitResult = Atomics.wait(isDoneView, 0, 0, 5000) | |
Atomics.store(isDoneView, 0, 0) | |
debugMain(`Unlocked: ${waitResult}`) | |
try { | |
const textDecoder = new TextDecoder() | |
const decoded = textDecoder.decode(dataView.subarray(0, dataLengthView[0])) // prettier-ignore | |
const result = JSON.parse(decoded) | |
debugMain('Finished') | |
lastResult = result | |
return result | |
} catch (error) { | |
debugMain('No result obtained; finished with last result') | |
return lastResult | |
} finally { | |
if (isRunningWithinCli) { | |
setTimeout(() => { | |
debugMain('Terminating worker') | |
worker.terminate() | |
}) | |
} | |
} | |
} | |
} | |
} | |
const workerThread = () => { | |
parentPort.on('message', async ({ src, filename, autoPreprocessConfig }) => { | |
const result = await preprocess({ | |
src, | |
filename, | |
autoPreprocessConfig, | |
}) | |
.then(result => { | |
debugWorker(`Preprocessed ${filename}`) | |
return result | |
}) | |
.catch(error => { | |
debugWorker('Failed to preprocess:', error) | |
return null | |
}) | |
const [isDoneView, dataView, dataLengthView] = workerData | |
const textEncoder = new TextEncoder() | |
const encodedResult = textEncoder.encode(result ? JSON.stringify(result) : '') // prettier-ignore | |
dataView.set(encodedResult, 0) | |
dataLengthView[0] = encodedResult.length | |
Atomics.store(isDoneView, 0, 1) | |
Atomics.notify(isDoneView, 0) | |
}) | |
} | |
const preprocess = async ({ src, filename, autoPreprocessConfig }) => { | |
let instance | |
let markup | |
let module | |
let style | |
const result = await svelteCompiler.preprocess( | |
src, | |
[ | |
{ | |
markup: ({ content }) => { | |
markup = { | |
original: content, | |
} | |
}, | |
script: ({ content, attributes }) => { | |
if ( | |
attributes.lang === 'ts' || | |
attributes.lang === 'typescript' || | |
attributes.type === 'text/typescript' | |
) { | |
const ast = esTree.parse(content, { loc: true }) | |
const obj = { | |
ast, | |
original: content, | |
ext: 'ts', | |
} | |
if (attributes.context) { | |
module = obj | |
} else { | |
instance = obj | |
} | |
} | |
}, | |
style: ({ content }) => { | |
style = { | |
original: content, | |
} | |
}, | |
}, | |
sveltePreprocess(autoPreprocessConfig), | |
{ | |
markup: ({ content }) => { | |
if (markup) { | |
markup.result = content | |
markup.diff = markup.original.length - content.length | |
} | |
}, | |
script: ({ content, attributes }) => { | |
const obj = attributes.context ? module : instance | |
if (obj) { | |
obj.result = content | |
obj.diff = obj.original.length - content.length | |
} | |
}, | |
style: ({ content }) => { | |
if (style) { | |
style.result = content | |
style.diff = style.original.length - content.length | |
} | |
}, | |
}, | |
], | |
{ filename: filename || 'unknown' }, | |
) | |
return { | |
...result, | |
instance, | |
markup, | |
module, | |
style, | |
} | |
} | |
if (isMainThread) { | |
module.exports = mainThread() | |
} else { | |
workerThread() | |
} |
Just updated it to const isRunningWithinCli = !process.argv.includes('--node-ipc')
.
That seems to have done the trick. Thanks for the quick reply and fix, you rock! 👍
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
process.env.npm_lifecycle_event
was undefined for me so in order to prevent the eslint CLI from hanging, I commented out lines 60 and 65. I hope that doesn’t mess up other stuff.