Skip to content

Commit

Permalink
crackle dev: add a --shim option (#168)
Browse files Browse the repository at this point in the history
  • Loading branch information
mrm007 authored Feb 7, 2024
1 parent 82675c6 commit 3e954b6
Show file tree
Hide file tree
Showing 13 changed files with 84 additions and 26 deletions.
14 changes: 14 additions & 0 deletions .changeset/cli-dev-shim.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
'@crackle/cli': minor
---

Add a `crackle dev --shim` option with choices `none` and `require` (default)

The `--webpack` option has been removed from the `dev` command in favour of the more generic `--shim` option.

Consumers should migrate to use `--shim=none` as follows:

```diff
-crackle dev --webpack
+crackle dev --shim=none
```
7 changes: 7 additions & 0 deletions .changeset/core-dev-shim.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@crackle/core': minor
---

Add a `dev.shim` config option with choices `none` and `require` (default)

The `dev.webpack` config option has been removed, replaced with `dev.shim: 'none'`
2 changes: 1 addition & 1 deletion fixtures/dev-entries-webpack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"dist"
],
"scripts": {
"dev": "crackle dev --webpack",
"dev": "crackle dev --shim=none",
"fix": "crackle fix",
"package": "crackle package"
},
Expand Down
10 changes: 6 additions & 4 deletions packages/cli/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { CrackleServer, UserConfig } from '@crackle/core';
import type { CrackleServer, UserConfig, ResolvedConfig } from '@crackle/core';
import { logger } from '@crackle/core/logger';
import { mergeConfig, resolveConfig } from '@crackle/core/resolve-config';
import yargs, { type ArgumentsCamelCase, type CommandModule } from 'yargs';
Expand Down Expand Up @@ -118,9 +118,11 @@ yargs(process.argv.slice(2))
command: 'dev',
describe: 'Generate entry points for local development',
builder: {
webpack: {
description: 'Generate Webpack-compatible shims',
type: 'boolean',
shim: {
description: 'Controls whether Crackle should generate a shim',
choices: ['require', 'none'] satisfies Array<
ResolvedConfig['dev']['shim']
>,
},
},
handler: async (overrides) => {
Expand Down
11 changes: 7 additions & 4 deletions packages/core/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,14 @@ export interface Config {
};
dev: {
/**
* Generate Webpack-compatible shims.
* Controls whether Crackle should generate a shim.
*
* @default false
* - 'require' creates a `require` shim using `createRequire`
* - 'none' does not add a shim
*
* @default 'require'
*/
webpack?: boolean;
shim?: 'require' | 'none';
};
package: {
/**
Expand Down Expand Up @@ -133,7 +136,7 @@ export const defaultConfig: Config = {
},
},
dev: {
webpack: false,
shim: 'require',
},
package: {
clean: true,
Expand Down
8 changes: 5 additions & 3 deletions packages/core/src/entries/dev.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { type PartialConfig, getConfig } from '../config';
import { type PartialConfig, getConfig, context } from '../config';
import { generateDevFiles } from '../utils/dev-entry-points';

export const dev = async (inlineConfig?: PartialConfig) => {
await getConfig(inlineConfig);
const config = await getConfig(inlineConfig);

await generateDevFiles();
await context.run(config, async () => {
await generateDevFiles();
});
};
31 changes: 25 additions & 6 deletions packages/core/src/utils/dev-entry-points.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,14 @@ const localLogger = logger.withDefaults({ tag: 'dev' });
const getReadableEntryName = (entry: PackageEntryPoint) =>
entry.isDefaultEntry ? 'index' : entry.entryName;

const getHookLoader = async (entry: PackageEntryPoint, format: Format) => {
interface HookLoader {
setup: string;
load: (importName: string) => string;
}
const getHookLoader = async (
entry: PackageEntryPoint,
format: Format,
): Promise<HookLoader> => {
const stringifyRelative = (p: string) =>
JSON.stringify(path.relative(entry.outputDir, p));

Expand All @@ -31,8 +38,17 @@ const getHookLoader = async (entry: PackageEntryPoint, format: Format) => {
// ! don't change this ! unbuild searches for the string and inserts its own shims
const rekwire = 'req' + 'uire';

let setup = '';
if (!config.dev.webpack) {
let setup: HookLoader['setup'] = '';
let load: HookLoader['load'] = (mod: string) =>
format === 'esm'
? `import * as ${mod} from ${stringifyRelative(entry.entryPath)};`
: `const ${mod} = ${rekwire}(${stringifyRelative(entry.entryPath)});`;

if (config.dev.shim === 'none') {
return { setup, load };
}

if (config.dev.shim === 'require') {
const shims = dedent`
import { createRequire } from "module";
Expand All @@ -46,8 +62,9 @@ const getHookLoader = async (entry: PackageEntryPoint, format: Format) => {
${rekwire}(${stringifyRelative(hookPath)});
`;
load = (mod) =>
`const ${mod} = ${rekwire}(${stringifyRelative(entry.entryPath)});`;
}
const load = `${rekwire}(${stringifyRelative(entry.entryPath)})`;

return {
setup,
Expand Down Expand Up @@ -94,7 +111,9 @@ const getCjsContents: GetContents = async (entry) => {
return dedent`
${setup}
module.exports = ${load};
${load('_mod')}
module.exports = _mod;
`;
};

Expand All @@ -117,7 +136,7 @@ const getEsmContents: GetContents = async (entry) => {
return dedent`
${setup}
const _mod = ${load};
${load('_mod')}
${exports
.map((specifier) =>
Expand Down
4 changes: 3 additions & 1 deletion tests/__snapshots__/dev/dev-entries-webpack/dist/cli.ts.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/* #region dist/cli.cjs */
module.exports = require("../src/entries/cli.ts");
const _mod = require("../src/entries/cli.ts");

module.exports = _mod;
/* #endregion */


Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/* #region dist/index.cjs */
module.exports = require("../src/index.ts");
const _mod = require("../src/index.ts");

module.exports = _mod;
/* #endregion */


Expand All @@ -16,7 +18,7 @@ export { default } from "../src/index";


/* #region dist/index.mjs */
const _mod = require("../src/index.ts");
import * as _mod from "../src/index.ts";

export const something = _mod.something;
export default _mod.default;
Expand Down
4 changes: 3 additions & 1 deletion tests/__snapshots__/dev/dev-entries/dist/cli.ts.snap
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
/* #region dist/cli.cjs */
require("../../../node_modules/.pnpm/tsx@[version]/node_modules/tsx/dist/cjs/index.cjs");

module.exports = require("../src/entries/cli.ts");
const _mod = require("../src/entries/cli.ts");

module.exports = _mod;
/* #endregion */


Expand Down
4 changes: 3 additions & 1 deletion tests/__snapshots__/dev/dev-entries/dist/index.ts.snap
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
/* #region dist/index.cjs */
require("../../../node_modules/.pnpm/tsx@[version]/node_modules/tsx/dist/cjs/index.cjs");

module.exports = require("../src/index.ts");
const _mod = require("../src/index.ts");

module.exports = _mod;
/* #endregion */


Expand Down
4 changes: 3 additions & 1 deletion tests/__snapshots__/dev/dev-entries/dist/re-export.ts.snap
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
/* #region dist/re-export.cjs */
require("../../../node_modules/.pnpm/tsx@[version]/node_modules/tsx/dist/cjs/index.cjs");

module.exports = require("../src/entries/re-export.ts");
const _mod = require("../src/entries/re-export.ts");

module.exports = _mod;
/* #endregion */


Expand Down
5 changes: 3 additions & 2 deletions tests/dev.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { UserConfig } from '@crackle/core';
import { dev } from '@crackle/core/dev';
import { resolveConfig } from '@crackle/core/resolve-config';
import fixturez from 'fixturez';
Expand All @@ -14,14 +15,14 @@ beforeAll(() => {
test.each`
name | options
${'dev-entries'} | ${undefined}
${'dev-entries-webpack'} | ${{ webpack: true }}
${'dev-entries-webpack'} | ${{ shim: 'none' } satisfies UserConfig['dev']}
`(
'fixture $name',
async ({ name: fixtureName, options }) => {
const fixtureDir = f.find(fixtureName);

const config = await resolveConfig({ cwd: fixtureDir });
await dev({ ...config, ...options });
await dev({ ...config, dev: options });

await snapshotOutput('dev', fixtureName);
},
Expand Down

0 comments on commit 3e954b6

Please sign in to comment.