forked from cockpit-project/cockpit-podman
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
maint: Drop webpack in favor of esbuild
Esbuild performance: $ time npm run build > build > node build.js real 0m7.747s user 0m12.328s sys 0m0.508s Webpack performance: [kkoukiou@sequioa cockpit-podman]$ time npm run build > build > webpack Webpack compiled successfully real 0m26.832s user 0m47.778s sys 0m1.640s For eslint integration there are two existing plugins [1], [2] but none can be used because of unsatisfied peer dependency version of esbuild. Let's just use our own eslint plugin for now. [1] to-codando/esbuild-plugin-linter#1 [2] robinloeffel/esbuild-plugin-eslint#5 TODO: - [ ] Bundle sizes are much bigger: evanw/esbuild#2933 - [ ] fail on eslint warnings eslint: eslint/eslint#16804 - [ ] sass plugin pulls in older/duplicate esbuild compiler: glromeo/esbuild-sass-plugin#122
- Loading branch information
1 parent
d023933
commit c580e08
Showing
11 changed files
with
263 additions
and
190 deletions.
There are no files selected for viewing
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import copy from 'esbuild-plugin-copy'; | ||
import esbuild from "esbuild"; | ||
import fs from "fs"; | ||
import path from "path"; | ||
import { cockpitPoPlugin } from './esbuild-cockpit-po-plugin.js'; | ||
import { cockpitRsyncPlugin } from './esbuild-rsync-plugin.js'; | ||
import { eslintPlugin } from './esbuild-eslint-plugin.js'; | ||
import { sassPlugin } from 'esbuild-sass-plugin'; | ||
import { stylelintPlugin } from './esbuild-stylelint-plugin.js'; | ||
|
||
const production = process.env.NODE_ENV === 'production'; | ||
/* Default to disable csslint for faster production builds */ | ||
const stylelint = process.env.STYLELINT ? (process.env.STYLELINT !== '0') : !production; | ||
/* List of directories to use when resolving import statements */ | ||
const nodePaths=['pkg/lib'] | ||
|
||
const context = await esbuild.context({ | ||
... !production ? { sourcemap: "external" } : {}, | ||
bundle: true, | ||
entryPoints: ["./src/index.js"], | ||
external: ['*.woff', '*.woff2', '*.jpg', '*.svg', '../../assets*'], // Allow external font files which live in ../../static/fonts | ||
legalComments: 'external', // Move all legal comments to a .LEGAL.txt file | ||
loader: { ".js": "jsx" }, | ||
minify: production, | ||
nodePaths, | ||
outdir: "./dist", | ||
target: ['es2020'], | ||
plugins: [ | ||
... stylelint ? [stylelintPlugin()] : [], | ||
... process.env.ESLINT !== '0' ? [eslintPlugin] : [], | ||
// Esbuild will only copy assets that are explicitly imported and used | ||
// in the code. This is a problem for index.html and manifest.json which are not imported | ||
copy({ | ||
assets: [ | ||
{ from: ['./src/manifest.json'], to: [ './manifest.json' ] }, | ||
{ from: ['./src/index.html'], to: ['./index.html'] }, | ||
] | ||
}), | ||
sassPlugin({ | ||
loadPaths: [...nodePaths, 'node_modules'], quietDeps: true, | ||
async transform(source, resolveDir, path) { | ||
if (path.includes('patternfly-4-cockpit.scss')) { | ||
return source | ||
.replace(/url.*patternfly-icons-fake-path.*;/g, 'url("../base1/fonts/patternfly.woff") format("woff");') | ||
.replace(/@font-face[^}]*patternfly-fonts-fake-path[^}]*}/g, ''); | ||
} | ||
return source; | ||
} | ||
}), | ||
cockpitPoPlugin, | ||
... process.env.RSYNC ? [cockpitRsyncPlugin()] : [], | ||
] | ||
}) | ||
|
||
// Manually do an incremental build | ||
const result = await context.rebuild() | ||
|
||
/* development options for faster iteration */ | ||
const watchMode = process.env.ESBUILD_WATCH === "true" || false; | ||
if(watchMode) { | ||
console.log("Running in watch mode"); | ||
// Enable watch mode | ||
await context.watch() | ||
} | ||
else { | ||
context.dispose(); | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import fs from "fs"; | ||
import glob from "glob"; | ||
import path from "path"; | ||
import Jed from "jed"; | ||
import gettext_parser from "gettext-parser"; | ||
|
||
const srcdir = process.env.SRCDIR || "./"; | ||
|
||
function get_po_files() { | ||
try { | ||
const linguas_file = path.resolve(srcdir, "po/LINGUAS"); | ||
const linguas = fs.readFileSync(linguas_file, 'utf8').match(/\S+/g); | ||
return linguas.map(lang => path.resolve(srcdir, 'po', lang + '.po')); | ||
} catch (error) { | ||
if (error.code !== 'ENOENT') { | ||
throw error; | ||
} | ||
|
||
/* No LINGUAS file? Fall back to globbing. | ||
* Note: we won't detect .po files being added in this case. | ||
*/ | ||
return glob.sync(path.resolve(srcdir, 'po/*.po')); | ||
} | ||
} | ||
|
||
function get_plural_expr(statement) { | ||
try { | ||
/* Check that the plural forms isn't being sneaky since we build a function here */ | ||
Jed.PF.parse(statement); | ||
} catch (ex) { | ||
console.error("bad plural forms: " + ex.message); | ||
process.exit(1); | ||
} | ||
|
||
const expr = statement.replace(/nplurals=[1-9]; plural=([^;]*);?$/, '(n) => $1'); | ||
if (expr === statement) { | ||
console.error("bad plural forms: " + statement); | ||
process.exit(1); | ||
} | ||
|
||
return expr; | ||
} | ||
|
||
function buildFile(po_file, outdir, subdir='', wrapper='cockpit.locale(PO_DATA)') { | ||
return new Promise((resolve, reject) => { | ||
const parsed = gettext_parser.po.parse(fs.readFileSync(po_file), 'utf8'); | ||
delete parsed.translations[""][""]; // second header copy | ||
|
||
const rtl_langs = ["ar", "fa", "he", "ur"]; | ||
const dir = rtl_langs.includes(parsed.headers.language) ? "rtl" : "ltr"; | ||
|
||
// cockpit.js only looks at "plural-forms" and "language" | ||
const chunks = [ | ||
'{\n', | ||
' "": {\n', | ||
` "plural-forms": ${get_plural_expr(parsed.headers['plural-forms'])},\n`, | ||
` "language": "${parsed.headers.language}",\n`, | ||
` "language-direction": "${dir}"\n`, | ||
' }' | ||
]; | ||
for (const [msgctxt, context] of Object.entries(parsed.translations)) { | ||
const context_prefix = msgctxt ? msgctxt + '\u0004' : ''; /* for cockpit.ngettext */ | ||
|
||
for (const [msgid, translation] of Object.entries(context)) { | ||
/* Only include msgids which appear in this source directory */ | ||
const references = translation.comments.reference.split(/\s/); | ||
if (!references.some(str => str.startsWith(`pkg/${subdir}`) || str.startsWith('src'))) | ||
continue; | ||
|
||
if (translation.comments.flag && translation.comments.flag.match(/\bfuzzy\b/)) | ||
continue; | ||
|
||
const key = JSON.stringify(context_prefix + msgid); | ||
// cockpit.js always ignores the first item | ||
chunks.push(`,\n ${key}: [\n null`); | ||
for (const str of translation.msgstr) { | ||
chunks.push(',\n ' + JSON.stringify(str)); | ||
} | ||
chunks.push('\n ]'); | ||
} | ||
} | ||
chunks.push('\n}'); | ||
|
||
const output = wrapper.replace('PO_DATA', chunks.join('')) + '\n'; | ||
|
||
const lang = path.basename(po_file).slice(0, -3); | ||
fs.writeFileSync(path.resolve(outdir, subdir + 'po.' + lang + '.js'), output); | ||
return resolve(); | ||
}); | ||
} | ||
|
||
export const cockpitPoPlugin = { | ||
name: 'cockpitPoPlugin', | ||
setup(build) { | ||
build.onEnd(async () => { | ||
await Promise.all(get_po_files().map(f => buildFile(f, build.initialOptions.outdir))); | ||
}); | ||
}, | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// FIXME: replace with plugin from npmjs if possible | ||
// Candidate [1] https://github.com/to-codando/esbuild-plugin-linter/issues/1 | ||
// Candidate [2] https://github.com/robinloeffel/esbuild-plugin-eslint/issues/5 | ||
|
||
import { ESLint } from 'eslint'; | ||
|
||
export const eslintPlugin = { | ||
name: 'eslintPlugin', | ||
setup(build) { | ||
const filesToLint = []; | ||
const eslint = new ESLint(); | ||
const filter = /src\/.*\.(jsx?|js?)$/; | ||
|
||
build.onLoad({ filter }, ({ path }) => { | ||
filesToLint.push(path); | ||
}); | ||
|
||
build.onEnd(async () => { | ||
const result = await eslint.lintFiles(filesToLint); | ||
const formatter = await eslint.loadFormatter('stylish'); | ||
const output = formatter.format(result); | ||
if (output.length > 0) { | ||
// eslint-disable-next-line no-console | ||
console.log(output); | ||
} | ||
}); | ||
}, | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import * as child_process from "child_process"; | ||
|
||
export const cockpitRsyncPlugin = (options = {}) => ({ | ||
name: 'cockpitRsyncPlugin', | ||
setup(build) { | ||
const dest = options.dest || ""; | ||
const source = options.source || "dist/"; | ||
|
||
// ensure the target directory exists | ||
child_process.spawnSync("ssh", [process.env.RSYNC, "mkdir", "-p", "/usr/local/share/cockpit/"], { stdio: "inherit" }); | ||
|
||
build.onEnd(() => { | ||
const proc = child_process.spawn( | ||
"rsync", ["--recursive", "--info=PROGRESS2", "--delete", | ||
source, process.env.RSYNC + ":/usr/local/share/cockpit/" + dest], { stdio: "inherit" } | ||
); | ||
proc.on('close', (code) => { | ||
if (code !== 0) { | ||
process.exit(1); | ||
} | ||
}); | ||
}); | ||
}, | ||
}); |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// FIXME: replace when issue get's fixed https://github.com/ordros/esbuild-plugin-stylelint/issues/1 | ||
|
||
import * as stylelint from 'stylelint'; | ||
import * as formatter from 'stylelint-formatter-pretty'; | ||
|
||
export const stylelintPlugin = ({ | ||
filter = /\.(s?css)$/, | ||
...stylelintOptions | ||
} = {}) => ({ | ||
name: 'stylelintPlugin', | ||
setup(build) { | ||
const targetFiles = []; | ||
build.onLoad({ filter }, ({ path }) => { | ||
if (!path.includes('node_modules')) { | ||
targetFiles.push(path); | ||
} | ||
}); | ||
|
||
build.onEnd(async () => { | ||
const result = await stylelint.default.lint({ | ||
formatter: formatter.default, | ||
...stylelintOptions, | ||
files: targetFiles, | ||
}); | ||
const { output } = result; | ||
if (output.length > 0) { | ||
console.log(output); | ||
} | ||
}); | ||
} | ||
}); |
Submodule node_modules
updated
7041 files
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
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
Oops, something went wrong.