Skip to content

Commit

Permalink
feat(nano-build): Refactor build options and add presets (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
alimd authored Dec 23, 2023
2 parents bf215b6 + 13b3d91 commit 407e8e7
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 81 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"nanolib",
"outdir",
"outfile",
"pmpa",
"tsbuildinfo",
"typeof"
]
Expand Down
108 changes: 75 additions & 33 deletions packages/nano-build/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,88 @@ Add the following scripts to your `package.json`:
```json
{
"scripts": {
"build": "nano-build",
"watch": "nano-build --watch",
"build": "nano-build --preset=module",
"watch": "yarn run build --watch",
"clean": "rm -rfv dist .tsbuildinfo"
}
}
```

## Presets

### default

```js
{
entryPoints: ['src/main.ts'],
outdir: 'dist',
logLevel: 'info',
platform: 'node',
target: 'es2020',
minify: true,
treeShaking: false,
sourcemap: true,
sourcesContent: true,
bundle: true,
splitting: false,
charset: 'utf8',
legalComments: 'none',
banner: {
js: "/* @package_name v@package_version */"
},
define: {
__package_version: `'@package_version'`,
},
}
```

### `--preset=module`

```js
{
...defaultPreset,
format: 'esm',
cjs: true,
mangleProps: '_$',
packages: 'external',
}
```

### `--preset=pwa`

```js
{
...defaultPreset,
format: 'iife',
platform: 'browser',
target: 'es2017',
mangleProps: '_$',
treeShaking: true,
sourcemap: false,
sourcesContent: false,
}
```

### `--preset=pmpa`

```js
{
...defaultPreset,
entryPoints: ['site/_ts/*.ts'],
outdir: 'dist/es',
format: 'iife',
platform: 'browser',
target: 'es2017',
mangleProps: '_$',
treeShaking: true,
sourcemap: false,
sourcesContent: false,
}
```

## Configuration

Add 'nano-build' field to your `package.json`:
Add 'nano-build' field to your `package.json` for overwriting configuration:

```json
{
Expand All @@ -41,33 +113,3 @@ Add 'nano-build' field to your `package.json`:
}
}
```

default configuration:

```json
{
"entryPoints": ["src/main.ts"],
"outdir": "dist",
"logLevel": "info",
"platform": "node",
"target": "es2020",
"format": "esm",
"cjs": true,
"minify": true,
"mangleProps": "_$",
"treeShaking": false,
"sourcemap": true,
"sourcesContent": true,
"bundle": true,
"packages": "external",
"splitting": false,
"charset": "utf8",
"legalComments": "none",
"banner": {
"js": "/* @package_name v@package_version */"
},
"define": {
"__package_version": "'@package_version'"
}
}
```
145 changes: 97 additions & 48 deletions packages/nano-build/nano-build.cjs
Original file line number Diff line number Diff line change
@@ -1,90 +1,139 @@
const {context, build} = require('esbuild');
const {resolve} = require('path');
const {existsSync} = require('fs');

const packageJsonPath = resolve(process.cwd(), 'package.json');
if (existsSync(packageJsonPath) === false) {
console.error('❌ package.json not found', {path: packageJsonPath});
process.exit(1);
}
const packageJson = require(packageJsonPath);

console.log('🚀 nano-build');
console.log('📦 ' + packageJson.name);
console.log('📦 %s\n', packageJson.name);

const watchMode = process.argv.includes('--watch');

const devMode = process.env.NODE_ENV !== 'production';

(async () => {
/**
* @type {import('esbuild').BuildOptions}
*/
const esbuildOptions = {
entryPoints: ['src/main.ts'],
outdir: 'dist',
logLevel: 'info',
platform: 'node',
target: 'es2020',
/**
* @type {import('esbuild').BuildOptions}
*/
const defaultOptions = {
entryPoints: ['src/main.ts'],
outdir: 'dist',
logLevel: 'info',
platform: 'node',
target: 'es2020',
minify: true,
treeShaking: false,
sourcemap: true,
sourcesContent: true,
bundle: true,
splitting: false,
charset: 'utf8',
legalComments: 'none',
banner: {
js: '/* ' + packageJson.name + ' v' + packageJson.version + ' */',
},
define: {
__package_version: `'${packageJson.version}'`,
},
};

const presetRecord = {
default: defaultOptions,
module: {
format: 'esm',
cjs: true,
minify: true,
mangleProps: '_$',
treeShaking: false,
sourcemap: true,
sourcesContent: true,
bundle: true,
packages: 'external',
splitting: false,
charset: 'utf8',
legalComments: 'none',
banner: {
js: '/* ' + packageJson.name + ' v' + packageJson.version + ' */',
},
define: {
__package_version: `'${packageJson.version}'`,
},
},
pwa: {
format: 'iife',
platform: 'browser',
target: 'es2017',
mangleProps: '_$',
treeShaking: true,
sourcemap: false,
sourcesContent: false,
},
pmpa: {
entryPoints: ['site/_ts/*.ts'],
outdir: 'dist/es',
format: 'iife',
platform: 'browser',
target: 'es2017',
mangleProps: '_$',
treeShaking: true,
sourcemap: false,
sourcesContent: false,
},
};

function getOptions() {
let presetName = process.argv.find((arg) => arg.startsWith('--preset='))?.split('=')[1] ?? 'default';
console.log('🔧 preset: %s', presetName);
const presetOptions = presetRecord[presetName];
if (!presetOptions) {
console.error('❌ preset not found', {preset: presetName});
process.exit(1);
}

const options = {
...defaultOptions,
...presetOptions,
...packageJson['nano-build'],
...packageJson['nano-build-' + (devMode ? 'development' : 'production')],
};

const alsoCjs = esbuildOptions.format === 'esm' && esbuildOptions.cjs;
delete esbuildOptions.cjs;

if (alsoCjs) {
esbuildOptions.outExtension = {
...esbuildOptions.outExtension,
'.js': '.mjs',
};
}

// Remove null fields from esbuildOptions
Object.keys(esbuildOptions).forEach((key) => {
if (esbuildOptions[key] === null) {
delete esbuildOptions[key];
Object.keys(options).forEach((key) => {
if (options[key] === null) {
delete options[key];
}
});

if (esbuildOptions.outdir !== undefined) {
delete esbuildOptions.outfile;
console.log('🛠️ options: %o\n', options);

if (typeof options.mangleProps === 'string') {
options.mangleProps = new RegExp(options.mangleProps);
}

console.log('esbuildOptions: %o', esbuildOptions);
return options;
}

async function nanoBuild(options) {
const alsoCjs = options.format === 'esm' && options.cjs;
delete options.cjs;

esbuildOptions.mangleProps = new RegExp(esbuildOptions.mangleProps);
if (alsoCjs) {
options.outExtension = {
...options.outExtension,
'.js': '.mjs',
};
}

if (watchMode) {
console.log('👀 Watching...');
const esbuildContext = await context(esbuildOptions);
const esbuildContext = await context(options);
esbuildContext.watch();
return;
}

// else
console.log('🛠️ Building...');
await build(esbuildOptions);
console.log('🛠️ Building...');
await build(options);
if (alsoCjs) {
await build({
...esbuildOptions,
...options,
format: 'cjs',
outExtension: {
...esbuildOptions.outExtension,
...options.outExtension,
'.js': '.cjs',
},
});
}
})();
}

nanoBuild(getOptions());

0 comments on commit 407e8e7

Please sign in to comment.