Skip to content

Instantly share code, notes, and snippets.

@michelson
Created January 23, 2022 01:26
Show Gist options
  • Save michelson/996ce4b3c05867aaa1b80f6f315724a1 to your computer and use it in GitHub Desktop.
Save michelson/996ce4b3c05867aaa1b80f6f315724a1 to your computer and use it in GitHub Desktop.
esbuild watch + babel macros
import babel from '@babel/core';
import fs from 'fs';
import path from 'path';
const pluginBabel = (options = {}) => ({
name: 'babel',
setup(build, { transform } = {}) {
const { filter = /.*/, namespace = '', config = {} } = options;
const transformContents = ({ args, contents }) => {
const babelOptions = babel.loadOptions({
...config,
filename: args.path,
caller: {
name: 'esbuild-plugin-babel',
supportsStaticESM: true
}
});
if (!babelOptions) return { contents };
if (babelOptions.sourceMaps) {
const filename = path.relative(process.cwd(), args.path);
babelOptions.sourceFileName = filename;
}
return new Promise((resolve, reject) => {
babel.transform(contents, babelOptions, (error, result) => {
if(error) {
console.log(error)
reject(error)
} else {
resolve({ contents: result.code });
}
});
});
};
if (transform) return transformContents(transform);
build.onLoad({ filter, namespace }, async args => {
if (args.path.includes('node_modules')) return null;
if(args.path.includes(".json") || args.path.includes(".png") || args.path.includes(".css") ) return null;
const contents = await fs.promises.readFile(args.path, 'utf8');
return transformContents({ args, contents });
});
}
});
export default pluginBabel;
module.exports = function (api) {
var validEnv = ['development', 'test', 'production'];
var currentEnv = api.env();
var isDevelopmentEnv = api.env('development');
var isProductionEnv = api.env('production');
var isTestEnv = api.env('test');
if (!validEnv.includes(currentEnv)) {
throw new Error(
'Please specify a valid `NODE_ENV` or ' +
'`BABEL_ENV` environment variables. Valid values are "development", ' +
'"test", and "production". Instead, received: ' +
JSON.stringify(currentEnv) +
'.'
);
}
return {
presets: [
['@babel/preset-react'],
['@babel/preset-typescript', { allExtensions: true, isTSX: true }],
].filter(Boolean),
plugins: [
'babel-plugin-macros',
[
'prismjs',
{
languages: ['javascript', 'css', 'markup', 'ruby', 'typescript'],
plugins: ['line-numbers'],
theme: 'twilight',
css: true,
},
],
].filter(Boolean),
};
};
import esbuild from 'esbuild';
import babel from './babel-esbuild.mjs';
import { createServer } from 'http'
const clients = []
const watch = process.argv.includes('--watch')
const minify = process.argv.includes('--minify')
const watchOptions = {
onRebuild(error) {
clients.forEach((res) => res.write("data: update\n\n"));
clients.length = 0;
console.log(error ? error : "load complete");
},
}
esbuild
.build({
logLevel: 'info',
define: {
'process.env.NODE_ENV': '"test"',
'global': 'window',
'process.env.NODE_DEBUG': '""',
},
platform: 'browser',
entryPoints: [
"app/javascript/application.js",
"app/javascript/embed.js",
"app/javascript/article.js",
"app/javascript/docs.js",
"app/javascript/locales.js",
],
bundle: true,
loader: {
'.png': 'file',
'.js': 'jsx',
},
minify: minify && minify,
publicPath: "/assets",
sourcemap: true,
//watch: !process.env.BUILD,
banner: {
js: ' (() => new EventSource("http://localhost:3001").onmessage = () => location.reload())();',
},
watch: watch && watchOptions,
outdir: 'app/assets/builds',
plugins: [
babel({
filter: /\.([^cpj].*|c([^s].*)?|cs([^s].*)?|css.+|p([^n].*)?|pn([^g].*)?|png.+|j([^s].*)?|js([^o].*)?|jso([^n].*)?|json.+)$/,
})
]
})
.then(result => {
console.log(result)
if (watch) {
console.log('Build finished, watching for changes...')
} else {
console.log('Build finished, Congrats')
}
}).catch(result => {
console.log(result)
process.exit(1)
})
createServer((req, res) => {
return clients.push(
res.writeHead(200, {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
"Access-Control-Allow-Origin": "*",
Connection: "keep-alive",
}),
);
}).listen(3001);
@michelson
Copy link
Author

run command with node esbuild.config.mjs --minify --watch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment