Skip to content

Commit

Permalink
feat(rspack): add generatePackageJson plugin (#341)
Browse files Browse the repository at this point in the history
Co-authored-by: Travis Tarr <[email protected]>
  • Loading branch information
travtarr and travtarr authored Oct 30, 2023
1 parent a070a75 commit 9e87815
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 6 deletions.
19 changes: 19 additions & 0 deletions e2e/rspack-e2e/tests/rspack.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,5 +123,24 @@ describe('rspack e2e', () => {

result = await runNxCommandAsync(`e2e ${app2}-e2e`);
expect(result.stdout).toContain('Successfully ran target e2e');

// Generate a Nest app and verify build output
const app3 = uniq('app3');
await runNxCommandAsync(
`generate @nx/rspack:app ${app3} --framework=nest --unitTestRunner=jest`
);
checkFilesExist(`${app3}/project.json`);

result = await runNxCommandAsync(`build ${app3}`);
expect(result.stdout).toContain('Successfully ran target build');
// Make sure expected files are present.
expect(listFiles(`dist/${app3}`)).toHaveLength(3);

result = await runNxCommandAsync(
`build ${app3} --generatePackageJson=true`
);
expect(result.stdout).toContain('Successfully ran target build');
// Make sure expected files are present.
expect(listFiles(`dist/${app3}`)).toHaveLength(5);
}, 200_000);
});
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"@types/fs-extra": "^11.0.1",
"@types/jest": "29.4.0",
"@types/node": "18.11.9",
"@types/webpack-sources": "^3.2.1",
"@typescript-eslint/eslint-plugin": "5.62.0",
"@typescript-eslint/parser": "5.62.0",
"chalk": "4.1.2",
Expand Down
4 changes: 3 additions & 1 deletion packages/rspack/src/executors/rspack/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export interface RspackExecutorSchema {
tsConfig: string;
typeCheck?: boolean;
outputPath: string;
outputFileName?: string;
indexHtml?: string;
mode?: Mode;
watch?: boolean;
Expand All @@ -15,9 +16,10 @@ export interface RspackExecutorSchema {
assets?: any[];
extractLicenses?: boolean;
fileReplacements?: FileReplacement[];
generatePackageJson?: boolean;
}

export interface FileReplacement {
replace: string;
with: string;
}
}
8 changes: 8 additions & 0 deletions packages/rspack/src/executors/rspack/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
"type": "string",
"description": "The output path for the bundle."
},
"outputFileName": {
"type": "string",
"description": "The main output entry file"
},
"tsConfig": {
"type": "string",
"description": "The tsconfig file to build the project."
Expand Down Expand Up @@ -89,6 +93,10 @@
"type": "string",
"description": "Mode to run the build in.",
"enum": ["development", "production", "none"]
},
"generatePackageJson": {
"type": "boolean",
"description": "Generates a `package.json` and pruned lock file with the project's `node_module` dependencies populated for installing in a container. If a `package.json` exists in the project's directory, it will be reused with dependencies populated."
}
},
"required": ["target", "main", "outputPath", "tsConfig", "rspackConfig"],
Expand Down
87 changes: 87 additions & 0 deletions packages/rspack/src/plugins/generate-package-json-plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import {
ExecutorContext,
detectPackageManager,
serializeJson,
type ProjectGraph,
} from '@nx/devkit';
import {
HelperDependency,
createLockFile,
createPackageJson,
getHelperDependenciesFromProjectGraph,
getLockFileName,
readTsConfig,
} from '@nx/js';
import { type Compiler, type RspackPluginInstance } from '@rspack/core';
import { RawSource } from 'webpack-sources';

const pluginName = 'GeneratePackageJsonPlugin';

export class GeneratePackageJsonPlugin implements RspackPluginInstance {
private readonly projectGraph: ProjectGraph;

constructor(
private readonly options: { tsConfig: string; outputFileName: string },
private readonly context: ExecutorContext
) {
this.projectGraph = context.projectGraph;
}

apply(compiler: Compiler): void {
compiler.hooks.thisCompilation.tap(pluginName, (compilation) => {
compilation.hooks.processAssets.tap(
{
name: pluginName,
stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL,
},
() => {
const helperDependencies = getHelperDependenciesFromProjectGraph(
this.context.root,
this.context.projectName,
this.projectGraph
);

const importHelpers = !!readTsConfig(this.options.tsConfig).options
.importHelpers;
const shouldAddHelperDependency =
importHelpers &&
helperDependencies.every(
(dep) => dep.target !== HelperDependency.tsc
);

if (shouldAddHelperDependency) {
helperDependencies.push({
type: 'static',
source: this.context.projectName,
target: HelperDependency.tsc,
});
}

const packageJson = createPackageJson(
this.context.projectName,
this.projectGraph,
{
target: this.context.targetName,
root: this.context.root,
isProduction: true,
helperDependencies: helperDependencies.map((dep) => dep.target),
}
);
packageJson.main = packageJson.main ?? this.options.outputFileName;

compilation.emitAsset(
'package.json',
new RawSource(serializeJson(packageJson))
);
const packageManager = detectPackageManager(this.context.root);
compilation.emitAsset(
getLockFileName(packageManager),
new RawSource(
createLockFile(packageJson, this.projectGraph, packageManager)
)
);
}
);
});
}
}
31 changes: 26 additions & 5 deletions packages/rspack/src/utils/with-nx.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { Configuration, ExternalItem, RspackPluginInstance, ResolveAlias } from '@rspack/core';
import {
Configuration,
ExternalItem,
ResolveAlias,
RspackPluginInstance,
} from '@rspack/core';
import { LicenseWebpackPlugin } from 'license-webpack-plugin';
import * as path from 'path';
import { GeneratePackageJsonPlugin } from '../plugins/generate-package-json-plugin';
import { getCopyPatterns } from './get-copy-patterns';
import { SharedConfigContext } from './model';
import { normalizeAssets } from './normalize-assets';
import { LicenseWebpackPlugin } from 'license-webpack-plugin';

export function withNx(_opts = {}) {
return function makeConfig(
Expand Down Expand Up @@ -37,10 +43,25 @@ export function withNx(_opts = {}) {
);
}

options.fileReplacements.forEach(item => {
if (options.generatePackageJson) {
const mainOutputFile =
options.main.split('/').pop().split('.')[0] + '.js';

plugins.push(
new GeneratePackageJsonPlugin(
{
tsConfig: options.tsConfig,
outputFileName: options.outputFileName ?? mainOutputFile,
},
context
)
);
}

options.fileReplacements.forEach((item) => {
alias[item.replace] = item.with;
})
});

const externals: ExternalItem = {};
let externalsType: Configuration['externalsType'];
if (options.target === 'node') {
Expand Down
14 changes: 14 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4202,6 +4202,11 @@
dependencies:
"@types/node" "*"

"@types/source-list-map@*":
version "0.1.3"
resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.3.tgz#077e15c87fe06520e30396a533bd9848e735ce9b"
integrity sha512-I9R/7fUjzUOyDy6AFkehCK711wWoAXEaBi80AfjZt1lIkbe6AcXKd3ckQc3liMvQExWvfOeh/8CtKzrfUFN5gA==

"@types/stack-utils@^2.0.0":
version "2.0.1"
resolved "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c"
Expand All @@ -4217,6 +4222,15 @@
resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d"
integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==

"@types/webpack-sources@^3.2.1":
version "3.2.1"
resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-3.2.1.tgz#98670b35fa799c44ac235910f3fda9bfdcdbc2c6"
integrity sha512-iLC3Fsx62ejm3ST3PQ8vBMC54Rb3EoCprZjeJGI5q+9QjfDLGt9jeg/k245qz1G9AQnORGk0vqPicJFPT1QODQ==
dependencies:
"@types/node" "*"
"@types/source-list-map" "*"
source-map "^0.7.3"

"@types/ws@^8.5.1":
version "8.5.4"
resolved "https://registry.npmjs.org/@types/ws/-/ws-8.5.4.tgz#bb10e36116d6e570dd943735f86c933c1587b8a5"
Expand Down

0 comments on commit 9e87815

Please sign in to comment.