2022-02-02 00:45:52 +09:00
|
|
|
#!/usr/bin/env node
|
|
|
|
|
2024-03-01 00:32:37 +09:00
|
|
|
import babel from '@babel/core';
|
|
|
|
import { createHash } from 'crypto';
|
|
|
|
import esbuild from 'esbuild';
|
|
|
|
import coffeeScriptPlugin from 'esbuild-coffeescript';
|
|
|
|
import { lessLoader } from 'esbuild-plugin-less';
|
|
|
|
import fsPromises from 'fs/promises';
|
2024-11-04 05:30:37 +09:00
|
|
|
import { globSync } from 'glob';
|
2022-02-04 04:46:03 +09:00
|
|
|
|
2024-03-01 00:32:37 +09:00
|
|
|
const outdir = 'app/assets/builds';
|
2022-02-04 04:46:03 +09:00
|
|
|
|
2022-02-05 23:41:35 +09:00
|
|
|
const plugins = [
|
|
|
|
coffeeScriptPlugin({
|
|
|
|
bare: true,
|
|
|
|
inlineMap: true
|
|
|
|
}),
|
2022-02-12 06:05:38 +09:00
|
|
|
lessLoader({
|
|
|
|
rootpath: '',
|
|
|
|
sourceMap: {
|
|
|
|
sourceMapFileInline: false
|
|
|
|
}
|
|
|
|
}),
|
2022-02-05 23:41:35 +09:00
|
|
|
{
|
|
|
|
name: 'babel',
|
|
|
|
setup (build) {
|
|
|
|
build.onEnd(async () => {
|
2024-03-01 00:32:37 +09:00
|
|
|
const esbuildFilepath = `${outdir}/application.js`;
|
|
|
|
const inputSourceMap = JSON.parse(await fsPromises.readFile(`${esbuildFilepath}.map`));
|
2022-02-05 23:41:35 +09:00
|
|
|
const options = {
|
2022-02-12 06:05:38 +09:00
|
|
|
inputSourceMap,
|
2022-02-05 23:41:35 +09:00
|
|
|
minified: true,
|
|
|
|
presets: [
|
|
|
|
['@babel/preset-env']
|
|
|
|
],
|
|
|
|
sourceMaps: true
|
2024-03-01 00:32:37 +09:00
|
|
|
};
|
|
|
|
const esbuildOutput = await fsPromises.readFile(esbuildFilepath);
|
|
|
|
const result = await babel.transformAsync(esbuildOutput, options);
|
|
|
|
const filename = 'application.jsout';
|
|
|
|
const outfileBabel = `${outdir}/${filename}`;
|
2022-02-05 23:41:35 +09:00
|
|
|
result.map.sources = result.map.sources
|
|
|
|
// CoffeeScript sourcemap and Esbuild sourcemap combined generates duplicated source paths
|
2024-11-04 05:30:37 +09:00
|
|
|
.map((path) => path.replace(/\.\.\/\.\.\/javascript(\/.+)?\/app\/javascript\//, '../../javascript/'));
|
2024-03-01 00:32:37 +09:00
|
|
|
const resultMap = JSON.stringify(result.map);
|
|
|
|
const resultMapHash = createHash('sha256').update(resultMap).digest('hex');
|
2022-02-04 06:40:58 +09:00
|
|
|
|
2024-11-04 05:30:37 +09:00
|
|
|
// add hash so it matches sprocket output
|
|
|
|
fsPromises.writeFile(outfileBabel, `${result.code}\n//# sourceMappingURL=${filename}-${resultMapHash}.map`);
|
|
|
|
fsPromises.writeFile(`${outfileBabel}.map`, JSON.stringify(result.map));
|
2024-03-01 00:32:37 +09:00
|
|
|
});
|
2022-02-05 23:41:35 +09:00
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: 'analyze',
|
|
|
|
setup (build) {
|
|
|
|
build.onEnd(async (result) => {
|
|
|
|
if (options.analyze) {
|
2024-03-01 00:32:37 +09:00
|
|
|
const analyzeResult = await esbuild.analyzeMetafile(result.metafile);
|
2022-02-04 06:27:00 +09:00
|
|
|
|
2024-03-01 00:32:37 +09:00
|
|
|
console.log(analyzeResult);
|
2022-02-05 23:41:35 +09:00
|
|
|
}
|
2024-03-01 00:32:37 +09:00
|
|
|
});
|
2022-02-05 23:41:35 +09:00
|
|
|
}
|
2024-11-04 05:30:37 +09:00
|
|
|
},
|
|
|
|
{
|
|
|
|
name: 'log',
|
|
|
|
setup (build) {
|
2024-12-08 05:24:32 +09:00
|
|
|
let startTime = Date.now();
|
2024-11-04 16:05:29 +09:00
|
|
|
|
2024-11-04 05:30:37 +09:00
|
|
|
build.onStart(() => {
|
2024-12-08 05:24:32 +09:00
|
|
|
startTime = Date.now();
|
2024-11-04 05:30:37 +09:00
|
|
|
console.log(new Date(), 'Build started');
|
|
|
|
});
|
|
|
|
build.onEnd(() => {
|
2024-11-04 16:05:29 +09:00
|
|
|
console.log(new Date(), `Build finished (${Date.now() - startTime}ms)`);
|
2024-11-04 05:30:37 +09:00
|
|
|
});
|
|
|
|
}
|
2022-02-12 06:05:38 +09:00
|
|
|
}
|
2024-03-01 00:32:37 +09:00
|
|
|
];
|
2022-02-02 00:45:52 +09:00
|
|
|
|
2024-03-01 00:32:37 +09:00
|
|
|
const args = process.argv.slice(2);
|
2022-02-04 06:40:58 +09:00
|
|
|
const options = {
|
|
|
|
watch: args.includes('--watch'),
|
|
|
|
analyze: args.includes('--analyze')
|
2024-03-01 00:32:37 +09:00
|
|
|
};
|
2022-02-04 06:40:58 +09:00
|
|
|
|
2024-11-04 07:10:58 +09:00
|
|
|
const config = {
|
2022-02-02 00:45:52 +09:00
|
|
|
bundle: true,
|
2024-11-04 05:30:37 +09:00
|
|
|
entryPoints: globSync('app/javascript/*.*'),
|
2022-02-12 06:05:38 +09:00
|
|
|
external: ['*.gif', '*.png'],
|
2022-02-04 06:40:58 +09:00
|
|
|
metafile: options.analyze,
|
2022-02-02 00:45:52 +09:00
|
|
|
nodePaths: ['app/javascript'],
|
2022-02-12 06:05:38 +09:00
|
|
|
outdir,
|
2022-02-05 23:41:35 +09:00
|
|
|
plugins,
|
2022-02-02 00:45:52 +09:00
|
|
|
resolveExtensions: ['.coffee', '.js'],
|
2024-11-04 05:30:37 +09:00
|
|
|
sourcemap: 'external'
|
2024-11-04 07:10:58 +09:00
|
|
|
};
|
2024-11-04 05:30:37 +09:00
|
|
|
|
|
|
|
if (options.watch) {
|
2024-11-04 07:10:58 +09:00
|
|
|
(await esbuild.context(config)).watch();
|
2024-11-04 05:30:37 +09:00
|
|
|
} else {
|
2024-11-04 07:10:58 +09:00
|
|
|
esbuild.build(config);
|
2024-11-04 05:30:37 +09:00
|
|
|
}
|