feat(bundling): move rollup to its own plugin (#12009)
This commit is contained in:
parent
fb25fdada5
commit
dd6addefc3
@ -16,6 +16,10 @@ module.exports = {
|
||||
scopes: [
|
||||
{ name: 'angular', description: 'anything Angular specific' },
|
||||
{ name: 'core', description: 'anything Nx core specific' },
|
||||
{
|
||||
name: 'bundling',
|
||||
description: 'anything bundling specific (e.g. rollup, webpack, etc.)',
|
||||
},
|
||||
{ name: 'detox', description: 'anything Detox specific' },
|
||||
{ name: 'devkit', description: 'devkit-related changes' },
|
||||
{ name: 'express', description: 'anything Express specific' },
|
||||
|
||||
310
docs/generated/packages/rollup.json
Normal file
310
docs/generated/packages/rollup.json
Normal file
@ -0,0 +1,310 @@
|
||||
{
|
||||
"githubRoot": "https://github.com/nrwl/nx/blob/master",
|
||||
"name": "rollup",
|
||||
"packageName": "@nrwl/rollup",
|
||||
"description": "The Nx Plugin for Rollup contains executors and generators that support building applications using Rollup",
|
||||
"root": "/packages/rollup",
|
||||
"source": "/packages/rollup/src",
|
||||
"documentation": [],
|
||||
"generators": [
|
||||
{
|
||||
"name": "init",
|
||||
"factory": "./src/generators/init/init#rollupInitGenerator",
|
||||
"schema": {
|
||||
"$schema": "http://json-schema.org/schema",
|
||||
"$id": "NxWebpackInit",
|
||||
"cli": "nx",
|
||||
"title": "Init Webpack Plugin",
|
||||
"description": "Init Webpack Plugin.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"compiler": {
|
||||
"type": "string",
|
||||
"enum": ["babel", "swc", "tsc"],
|
||||
"description": "The compiler to initialize for.",
|
||||
"default": "babel"
|
||||
},
|
||||
"skipFormat": {
|
||||
"description": "Skip formatting files.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"presets": []
|
||||
},
|
||||
"description": "Initialize the `@nrwl/rollup` plugin.",
|
||||
"aliases": ["ng-add"],
|
||||
"hidden": true,
|
||||
"implementation": "/packages/rollup/src/generators/init/init#rollupInitGenerator.ts",
|
||||
"path": "/packages/rollup/src/generators/init/schema.json"
|
||||
},
|
||||
{
|
||||
"name": "rollup-project",
|
||||
"factory": "./src/generators/rollup-project/rollup-project#rollupProjectGenerator",
|
||||
"schema": {
|
||||
"$schema": "http://json-schema.org/schema",
|
||||
"$id": "NxRollupProject",
|
||||
"cli": "nx",
|
||||
"title": "Add Rollup Configuration to a project",
|
||||
"description": "Add Rollup Configuration to a project.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"project": {
|
||||
"type": "string",
|
||||
"description": "The name of the project.",
|
||||
"$default": { "$source": "argv", "index": 0 },
|
||||
"x-dropdown": "project",
|
||||
"x-prompt": "What is the name of the project to set up a rollup for?"
|
||||
},
|
||||
"compiler": {
|
||||
"type": "string",
|
||||
"enum": ["babel", "swc", "tsc"],
|
||||
"description": "The compiler to use to build source.",
|
||||
"default": "babel"
|
||||
},
|
||||
"main": {
|
||||
"type": "string",
|
||||
"description": "Path relative to the workspace root for the main entry file. Defaults to '<projectRoot>/src/main.ts'.",
|
||||
"alias": "entryFile"
|
||||
},
|
||||
"tsConfig": {
|
||||
"type": "string",
|
||||
"description": "Path relative to the workspace root for the tsconfig file to build with. Defaults to '<projectRoot>/tsconfig.app.json'."
|
||||
},
|
||||
"skipFormat": {
|
||||
"description": "Skip formatting files.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"skipPackageJson": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Do not add dependencies to `package.json`."
|
||||
},
|
||||
"importPath": {
|
||||
"type": "string",
|
||||
"description": "The library name used to import it, like `@myorg/my-awesome-lib`."
|
||||
},
|
||||
"external": {
|
||||
"type": "array",
|
||||
"description": "A list of external modules that will not be bundled (`react`, `react-dom`, etc.).",
|
||||
"items": { "type": "string" }
|
||||
},
|
||||
"rollupConfig": {
|
||||
"type": "string",
|
||||
"description": "Path relative to workspace root to a custom rollup file that takes a config object and returns an updated config."
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"presets": []
|
||||
},
|
||||
"description": "Add rollup configuration to a project.",
|
||||
"hidden": true,
|
||||
"implementation": "/packages/rollup/src/generators/rollup-project/rollup-project#rollupProjectGenerator.ts",
|
||||
"aliases": [],
|
||||
"path": "/packages/rollup/src/generators/rollup-project/schema.json"
|
||||
}
|
||||
],
|
||||
"executors": [
|
||||
{
|
||||
"name": "rollup",
|
||||
"implementation": "/packages/rollup/src/executors/rollup/rollup.impl.ts",
|
||||
"schema": {
|
||||
"title": "Web Library Rollup Target (Experimental)",
|
||||
"description": "Packages a library for different web usages (`UMD`, `ESM`, `CJS`).",
|
||||
"cli": "nx",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"project": {
|
||||
"type": "string",
|
||||
"description": "The path to package.json file."
|
||||
},
|
||||
"main": {
|
||||
"type": "string",
|
||||
"description": "The path to the entry file, relative to project.",
|
||||
"alias": "entryFile",
|
||||
"x-completion-type": "file",
|
||||
"x-completion-glob": "**/*@(.js|.ts)"
|
||||
},
|
||||
"outputPath": {
|
||||
"type": "string",
|
||||
"description": "The output path of the generated files.",
|
||||
"x-completion-type": "directory"
|
||||
},
|
||||
"outputFileName": {
|
||||
"type": "string",
|
||||
"description": "Name of the main output file. Defaults same basename as 'main' file."
|
||||
},
|
||||
"deleteOutputPath": {
|
||||
"type": "boolean",
|
||||
"description": "Delete the output path before building.",
|
||||
"default": true
|
||||
},
|
||||
"tsConfig": {
|
||||
"type": "string",
|
||||
"description": "The path to tsconfig file.",
|
||||
"x-completion-type": "file",
|
||||
"x-completion-glob": "tsconfig.*.json"
|
||||
},
|
||||
"format": {
|
||||
"type": "array",
|
||||
"description": "List of module formats to output. Defaults to matching format from tsconfig (e.g. CJS for CommonJS, and ESM otherwise).",
|
||||
"alias": "f",
|
||||
"items": { "type": "string", "enum": ["esm", "umd", "cjs"] }
|
||||
},
|
||||
"external": {
|
||||
"type": "array",
|
||||
"description": "A list of external modules that will not be bundled (`react`, `react-dom`, etc.).",
|
||||
"items": { "type": "string" }
|
||||
},
|
||||
"watch": {
|
||||
"type": "boolean",
|
||||
"description": "Enable re-building when files change.",
|
||||
"default": false
|
||||
},
|
||||
"updateBuildableProjectDepsInPackageJson": {
|
||||
"type": "boolean",
|
||||
"description": "Update buildable project dependencies in `package.json`.",
|
||||
"default": true
|
||||
},
|
||||
"buildableProjectDepsInPackageJsonType": {
|
||||
"type": "string",
|
||||
"description": "When `updateBuildableProjectDepsInPackageJson` is `true`, this adds dependencies to either `peerDependencies` or `dependencies`.",
|
||||
"enum": ["dependencies", "peerDependencies"],
|
||||
"default": "peerDependencies"
|
||||
},
|
||||
"rollupConfig": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"x-completion-type": "file",
|
||||
"x-completion-glob": "rollup?(*)@(.js|.ts)"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"x-completion-type": "file",
|
||||
"x-completion-glob": "rollup?(*)@(.js|.ts)"
|
||||
}
|
||||
],
|
||||
"description": "Path to a function which takes a rollup config and returns an updated rollup config."
|
||||
},
|
||||
"umdName": {
|
||||
"type": "string",
|
||||
"description": "The name of your module in `UMD` format. Defaulted to your project name."
|
||||
},
|
||||
"globals": {
|
||||
"description": "A mapping of node modules to their `UMD` global names. Used by the `UMD` bundle.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"moduleId": {
|
||||
"type": "string",
|
||||
"description": "The node module to map from (e.g. `react-dom`)."
|
||||
},
|
||||
"global": {
|
||||
"type": "string",
|
||||
"description": "The global name to map to (e.g. `ReactDOM`)."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["moduleId", "global"]
|
||||
},
|
||||
"default": []
|
||||
},
|
||||
"extractCss": {
|
||||
"type": ["boolean", "string"],
|
||||
"description": "CSS files will be extracted to the output folder. Alternatively custom filename can be provided (e.g. styles.css)",
|
||||
"default": true
|
||||
},
|
||||
"assets": {
|
||||
"type": "array",
|
||||
"description": "List of static assets.",
|
||||
"default": [],
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"glob": {
|
||||
"type": "string",
|
||||
"description": "The pattern to match."
|
||||
},
|
||||
"input": {
|
||||
"type": "string",
|
||||
"description": "The input directory path in which to apply `glob`. Defaults to the project root."
|
||||
},
|
||||
"output": {
|
||||
"type": "string",
|
||||
"description": "Relative path within the output folder."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["glob", "input", "output"]
|
||||
},
|
||||
{ "type": "string" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"compiler": {
|
||||
"type": "string",
|
||||
"enum": ["babel", "swc", "tsc"],
|
||||
"default": "babel",
|
||||
"description": "Which compiler to use."
|
||||
},
|
||||
"javascriptEnabled": {
|
||||
"type": "boolean",
|
||||
"description": "Sets `javascriptEnabled` option for less loader",
|
||||
"default": false
|
||||
},
|
||||
"generateExportsField": {
|
||||
"type": "boolean",
|
||||
"description": "Generate package.json with 'exports' field. This field defines entry points in the package and is used by Node and the TypeScript compiler.",
|
||||
"default": false
|
||||
},
|
||||
"skipTypeField": {
|
||||
"type": "boolean",
|
||||
"description": "Prevents 'type' field from being added to compiled package.json file. Only use this if you are having an issue with this field.",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"required": ["tsConfig", "project", "main", "outputPath"],
|
||||
"definitions": {
|
||||
"assetPattern": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"glob": {
|
||||
"type": "string",
|
||||
"description": "The pattern to match."
|
||||
},
|
||||
"input": {
|
||||
"type": "string",
|
||||
"description": "The input directory path in which to apply `glob`. Defaults to the project root."
|
||||
},
|
||||
"output": {
|
||||
"type": "string",
|
||||
"description": "Relative path within the output folder."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["glob", "input", "output"]
|
||||
},
|
||||
{ "type": "string" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"presets": []
|
||||
},
|
||||
"description": "Bundle a package using Rollup.",
|
||||
"aliases": [],
|
||||
"hidden": false,
|
||||
"path": "/packages/rollup/src/executors/rollup/schema.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -294,6 +294,16 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "rollup",
|
||||
"packageName": "rollup",
|
||||
"description": "The Nx Plugin for Rollup contains executors and generators that support building applications using Rollup",
|
||||
"path": "generated/packages/rollup.json",
|
||||
"schemas": {
|
||||
"executors": ["rollup"],
|
||||
"generators": ["init", "rollup-project"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "storybook",
|
||||
"packageName": "storybook",
|
||||
|
||||
@ -155,7 +155,7 @@ describe('Next.js Applications', () => {
|
||||
const appName = uniq('app');
|
||||
const jsLib = uniq('tslib');
|
||||
|
||||
const port = 4201;
|
||||
const port = 4200;
|
||||
|
||||
runCLI(`generate @nrwl/next:app ${appName}`);
|
||||
runCLI(`generate @nrwl/js:lib ${jsLib} --no-interactive`);
|
||||
@ -217,12 +217,7 @@ describe('Next.js Applications', () => {
|
||||
expect(apiData).toContain(`Welcome`);
|
||||
expect(pageData).toContain(`test value from a file`);
|
||||
|
||||
try {
|
||||
await promisifiedTreeKill(p.pid, 'SIGKILL');
|
||||
expect(await killPorts(port)).toBeTruthy();
|
||||
} catch (err) {
|
||||
expect(err).toBeFalsy();
|
||||
}
|
||||
await killPorts();
|
||||
}, 300_000);
|
||||
|
||||
it('should support custom next.config.js and output it in dist', async () => {
|
||||
|
||||
11
e2e/rollup/jest.config.ts
Normal file
11
e2e/rollup/jest.config.ts
Normal file
@ -0,0 +1,11 @@
|
||||
/* eslint-disable */
|
||||
export default {
|
||||
transform: {
|
||||
'^.+\\.[tj]sx?$': 'ts-jest',
|
||||
},
|
||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
|
||||
maxWorkers: 1,
|
||||
globals: { 'ts-jest': { tsconfig: '<rootDir>/tsconfig.spec.json' } },
|
||||
displayName: 'e2e-rollup',
|
||||
preset: '../../jest.preset.js',
|
||||
};
|
||||
34
e2e/rollup/project.json
Normal file
34
e2e/rollup/project.json
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "e2e/rollup",
|
||||
"projectType": "application",
|
||||
"targets": {
|
||||
"e2e": {
|
||||
"executor": "nx:run-commands",
|
||||
"options": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "yarn e2e-start-local-registry"
|
||||
},
|
||||
{
|
||||
"command": "yarn e2e-build-package-publish"
|
||||
},
|
||||
{
|
||||
"command": "nx run-e2e-tests e2e-rollup"
|
||||
}
|
||||
],
|
||||
"parallel": false
|
||||
}
|
||||
},
|
||||
"run-e2e-tests": {
|
||||
"executor": "@nrwl/jest:jest",
|
||||
"options": {
|
||||
"jestConfig": "e2e/rollup/jest.config.ts",
|
||||
"passWithNoTests": true,
|
||||
"runInBand": true
|
||||
},
|
||||
"outputs": ["coverage/e2e/rollup"]
|
||||
}
|
||||
},
|
||||
"implicitDependencies": ["rollup"]
|
||||
}
|
||||
58
e2e/rollup/src/rollup.test.ts
Normal file
58
e2e/rollup/src/rollup.test.ts
Normal file
@ -0,0 +1,58 @@
|
||||
import {
|
||||
cleanupProject,
|
||||
newProject,
|
||||
rmDist,
|
||||
runCLI,
|
||||
runCommand,
|
||||
uniq,
|
||||
updateFile,
|
||||
updateProjectConfig,
|
||||
} from '@nrwl/e2e/utils';
|
||||
|
||||
describe('Rollup Plugin', () => {
|
||||
beforeEach(() => newProject());
|
||||
// afterEach(() => cleanupProject());
|
||||
|
||||
it('should be able to setup project to build node programs with rollup and different compilers', async () => {
|
||||
const myPkg = uniq('my-pkg');
|
||||
runCLI(`generate @nrwl/js:lib ${myPkg} --buildable=false`);
|
||||
updateFile(`libs/${myPkg}/src/index.ts`, `console.log('Hello');\n`);
|
||||
|
||||
// babel (default)
|
||||
runCLI(
|
||||
`generate @nrwl/rollup:rollup-project ${myPkg} --target=node --tsConfig=libs/${myPkg}/tsconfig.lib.json --main=libs/${myPkg}/src/index.ts`
|
||||
);
|
||||
rmDist();
|
||||
runCLI(`build ${myPkg}`);
|
||||
let output = runCommand(`node dist/libs/${myPkg}/index.cjs`);
|
||||
expect(output).toMatch(/Hello/);
|
||||
|
||||
updateProjectConfig(myPkg, (config) => {
|
||||
delete config.targets.build;
|
||||
return config;
|
||||
});
|
||||
|
||||
// swc
|
||||
runCLI(
|
||||
`generate @nrwl/rollup:rollup-project ${myPkg} --target=node --tsConfig=libs/${myPkg}/tsconfig.lib.json --main=libs/${myPkg}/src/index.ts --compiler=swc`
|
||||
);
|
||||
rmDist();
|
||||
runCLI(`build ${myPkg}`);
|
||||
output = runCommand(`node dist/libs/${myPkg}/index.cjs`);
|
||||
expect(output).toMatch(/Hello/);
|
||||
|
||||
updateProjectConfig(myPkg, (config) => {
|
||||
delete config.targets.build;
|
||||
return config;
|
||||
});
|
||||
|
||||
// tsc
|
||||
runCLI(
|
||||
`generate @nrwl/rollup:rollup-project ${myPkg} --target=node --tsConfig=libs/${myPkg}/tsconfig.lib.json --main=libs/${myPkg}/src/index.ts --compiler=tsc`
|
||||
);
|
||||
rmDist();
|
||||
runCLI(`build ${myPkg}`);
|
||||
output = runCommand(`node dist/libs/${myPkg}/index.cjs`);
|
||||
expect(output).toMatch(/Hello/);
|
||||
}, 500000);
|
||||
});
|
||||
13
e2e/rollup/tsconfig.json
Normal file
13
e2e/rollup/tsconfig.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"types": ["node", "jest"]
|
||||
},
|
||||
"include": [],
|
||||
"files": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
20
e2e/rollup/tsconfig.spec.json
Normal file
20
e2e/rollup/tsconfig.spec.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"module": "commonjs",
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
"include": [
|
||||
"**/*.test.ts",
|
||||
"**/*.spec.ts",
|
||||
"**/*.spec.tsx",
|
||||
"**/*.test.tsx",
|
||||
"**/*.spec.js",
|
||||
"**/*.test.js",
|
||||
"**/*.spec.jsx",
|
||||
"**/*.test.jsx",
|
||||
"**/*.d.ts",
|
||||
"jest.config.ts"
|
||||
]
|
||||
}
|
||||
@ -313,6 +313,7 @@ export function newProject({
|
||||
`@nrwl/next`,
|
||||
`@nrwl/node`,
|
||||
`@nrwl/nx-plugin`,
|
||||
`@nrwl/rollup`,
|
||||
`@nrwl/react`,
|
||||
`@nrwl/storybook`,
|
||||
`@nrwl/web`,
|
||||
|
||||
@ -33,8 +33,8 @@ describe('file-server', () => {
|
||||
try {
|
||||
await promisifiedTreeKill(p.pid, 'SIGKILL');
|
||||
await killPorts(port);
|
||||
} catch (err) {
|
||||
expect(err).toBeFalsy();
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}, 1000000);
|
||||
});
|
||||
|
||||
177
nx-dev/nx-dev/public/images/icons/rollup.svg
Normal file
177
nx-dev/nx-dev/public/images/icons/rollup.svg
Normal file
@ -0,0 +1,177 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="100 100 800 800"
|
||||
id="svg61"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs65" />
|
||||
<style
|
||||
id="style2">.st0{fill:url(#XMLID_4_);} .st1{fill:url(#XMLID_5_);} .st2{fill:url(#XMLID_8_);} .st3{fill:url(#XMLID_9_);} .st4{fill:url(#XMLID_11_);} .st5{opacity:0.3;fill:url(#XMLID_16_);}</style>
|
||||
<g
|
||||
id="XMLID_14_">
|
||||
<linearGradient
|
||||
id="XMLID_4_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="444.469"
|
||||
y1="526.051"
|
||||
x2="598.469"
|
||||
y2="562.051">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#000000"
|
||||
id="stop4" />
|
||||
<stop
|
||||
offset=".157"
|
||||
stop-color="#000000"
|
||||
id="stop6" />
|
||||
<stop
|
||||
offset=".434"
|
||||
stop-color="#000000"
|
||||
id="stop8" />
|
||||
<stop
|
||||
offset=".714"
|
||||
stop-color="#000000"
|
||||
id="stop10" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#000000"
|
||||
id="stop12" />
|
||||
</linearGradient>
|
||||
<path
|
||||
id="XMLID_15_"
|
||||
class="st0"
|
||||
d="M721 410c0-33.6-8.8-65.1-24.3-92.4-41.1-42.3-130.5-52.1-152.7-.2-22.8 53.2 38.3 112.4 65 107.7 34-6-6-84-6-84 52 98 40 68-54 158S359 779 345 787c-.6.4-1.2.7-1.9 1h368.7c6.5 0 10.7-6.9 7.8-12.7l-96.4-190.8c-2.1-4.1-.6-9.2 3.4-11.5C683 540.6 721 479.8 721 410z" />
|
||||
</g>
|
||||
<g
|
||||
id="XMLID_2_">
|
||||
<linearGradient
|
||||
id="XMLID_5_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="420.382"
|
||||
y1="475.002"
|
||||
x2="696.383"
|
||||
y2="689.002">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#000"
|
||||
id="stop17" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#000000"
|
||||
id="stop19" />
|
||||
</linearGradient>
|
||||
<path
|
||||
id="XMLID_10_"
|
||||
class="st1"
|
||||
d="M721 410c0-33.6-8.8-65.1-24.3-92.4-41.1-42.3-130.5-52.1-152.7-.2-22.8 53.2 38.3 112.4 65 107.7 34-6-6-84-6-84 52 98 40 68-54 158S359 779 345 787c-.6.4-1.2.7-1.9 1h368.7c6.5 0 10.7-6.9 7.8-12.7l-96.4-190.8c-2.1-4.1-.6-9.2 3.4-11.5C683 540.6 721 479.8 721 410z" />
|
||||
</g>
|
||||
<linearGradient
|
||||
id="XMLID_8_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="429.386"
|
||||
y1="517.156"
|
||||
x2="469.386"
|
||||
y2="559.156">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#000000"
|
||||
id="stop24" />
|
||||
<stop
|
||||
offset=".157"
|
||||
stop-color="#000000"
|
||||
id="stop26" />
|
||||
<stop
|
||||
offset=".434"
|
||||
stop-color="#000000"
|
||||
id="stop28" />
|
||||
<stop
|
||||
offset=".714"
|
||||
stop-color="#000000"
|
||||
id="stop30" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#000000"
|
||||
id="stop32" />
|
||||
</linearGradient>
|
||||
<path
|
||||
id="XMLID_3_"
|
||||
class="st2"
|
||||
d="M345 787c14-8 110-198 204-288s106-60 54-158c0 0-199 279-271 417" />
|
||||
<g
|
||||
id="XMLID_7_">
|
||||
<linearGradient
|
||||
id="XMLID_9_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="502.111"
|
||||
y1="589.457"
|
||||
x2="490.111"
|
||||
y2="417.457">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#000000"
|
||||
id="stop36" />
|
||||
<stop
|
||||
offset=".157"
|
||||
stop-color="#000000"
|
||||
id="stop38" />
|
||||
<stop
|
||||
offset=".434"
|
||||
stop-color="#000000"
|
||||
id="stop40" />
|
||||
<stop
|
||||
offset=".714"
|
||||
stop-color="#000000"
|
||||
id="stop42" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#000000"
|
||||
id="stop44" />
|
||||
</linearGradient>
|
||||
<path
|
||||
id="XMLID_12_"
|
||||
class="st3"
|
||||
d="M373 537c134.4-247.1 152-272 222-272 36.8 0 73.9 16.6 97.9 46.1-32.7-52.7-90.6-88-156.9-89H307.7c-4.8 0-8.7 3.9-8.7 8.7V691c13.6-35.1 36.7-85.3 74-154z" />
|
||||
</g>
|
||||
<linearGradient
|
||||
id="XMLID_11_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="450.125"
|
||||
y1="514.209"
|
||||
x2="506.943"
|
||||
y2="552.846">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#FFFFFF"
|
||||
id="stop49" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#FFFFFF"
|
||||
id="stop51" />
|
||||
</linearGradient>
|
||||
<path
|
||||
id="XMLID_6_"
|
||||
class="st4"
|
||||
d="M549 499c-94 90-190 280-204 288s-37.5 9-50-5c-13.3-14.9-34-39 78-245 134.4-247.1 152-272 222-272 36.8 0 73.9 16.6 97.9 46.1 1.3 2.1 2.6 4.3 3.9 6.5-41.1-42.3-130.5-52.1-152.7-.2-22.8 53.2 38.3 112.4 65 107.7 34-6-6-84-6-84C655 439 643 409 549 499z" />
|
||||
<linearGradient
|
||||
id="XMLID_16_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="508.333"
|
||||
y1="295.758"
|
||||
x2="450.333"
|
||||
y2="933.758">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#FFF"
|
||||
id="stop55" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#FFF"
|
||||
stop-opacity="0"
|
||||
id="stop57" />
|
||||
</linearGradient>
|
||||
<path
|
||||
id="XMLID_13_"
|
||||
class="st5"
|
||||
d="M384 548c134.4-247.1 152-272 222-272 30.3 0 60.8 11.3 84 31.7-24-27.4-59.6-42.7-95-42.7-70 0-87.6 24.9-222 272-112 206-91.3 230.1-78 245 1.9 2.1 4.1 3.9 6.4 5.4-11.7-17-16.9-56.5 82.6-239.4z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.8 KiB |
@ -16,6 +16,7 @@ export const iconsMap: Record<string, string> = {
|
||||
'nx-plugin': '/images/icons/nx.svg',
|
||||
react: '/images/icons/react.svg',
|
||||
'react-native': '/images/icons/react.svg',
|
||||
rollup: '/images/icons/rollup.svg',
|
||||
storybook: '/images/icons/storybook.svg',
|
||||
web: '/images/icons/html5.svg',
|
||||
webpack: '/images/icons/webpack.svg',
|
||||
|
||||
25
packages/rollup/.eslintrc.json
Normal file
25
packages/rollup/.eslintrc.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"extends": ["../../.eslintrc.json"],
|
||||
"ignorePatterns": ["!**/*"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.ts", "*.tsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["./package.json", "./generators.json", "./executors.json"],
|
||||
"parser": "jsonc-eslint-parser",
|
||||
"rules": {
|
||||
"@nrwl/nx/nx-plugin-checks": "error"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
13
packages/rollup/README.md
Normal file
13
packages/rollup/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
<p style="text-align: center;"><img src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx.png" width="600" alt="Nx - Smart, Fast and Extensible Build System"></p>
|
||||
|
||||
{{links}}
|
||||
|
||||
<hr>
|
||||
|
||||
# Nx: Smart, Fast and Extensible Build System
|
||||
|
||||
Nx is a next generation build system with first class monorepo support and powerful integrations.
|
||||
|
||||
This package is a [Rollup plugin for Nx](https://nx.dev/packages/rollup).
|
||||
|
||||
{{content}}
|
||||
16
packages/rollup/executors.json
Normal file
16
packages/rollup/executors.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"builders": {
|
||||
"rollup": {
|
||||
"implementation": "./src/executors/rollup/compat",
|
||||
"schema": "./src/executors/rollup/schema.json",
|
||||
"description": "Bundle a package using Rollup."
|
||||
}
|
||||
},
|
||||
"executors": {
|
||||
"rollup": {
|
||||
"implementation": "./src/executors/rollup/rollup.impl",
|
||||
"schema": "./src/executors/rollup/schema.json",
|
||||
"description": "Bundle a package using Rollup."
|
||||
}
|
||||
}
|
||||
}
|
||||
33
packages/rollup/generators.json
Normal file
33
packages/rollup/generators.json
Normal file
@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "Nx rollup",
|
||||
"version": "0.1",
|
||||
"schematics": {
|
||||
"init": {
|
||||
"factory": "./src/generators/init/init#rollupInitSchematic",
|
||||
"schema": "./src/generators/init/schema.json",
|
||||
"description": "Initialize the `@nrwl/rollup` plugin.",
|
||||
"hidden": true
|
||||
},
|
||||
"rollup-project": {
|
||||
"factory": "./src/generators/rollup-project/rollup-project#rollupProjectSchematic",
|
||||
"schema": "./src/generators/rollup-project/schema.json",
|
||||
"description": "Add rollup configuration to a project.",
|
||||
"hidden": true
|
||||
}
|
||||
},
|
||||
"generators": {
|
||||
"init": {
|
||||
"factory": "./src/generators/init/init#rollupInitGenerator",
|
||||
"schema": "./src/generators/init/schema.json",
|
||||
"description": "Initialize the `@nrwl/rollup` plugin.",
|
||||
"aliases": ["ng-add"],
|
||||
"hidden": true
|
||||
},
|
||||
"rollup-project": {
|
||||
"factory": "./src/generators/rollup-project/rollup-project#rollupProjectGenerator",
|
||||
"schema": "./src/generators/rollup-project/schema.json",
|
||||
"description": "Add rollup configuration to a project.",
|
||||
"hidden": true
|
||||
}
|
||||
}
|
||||
}
|
||||
2
packages/rollup/index.ts
Normal file
2
packages/rollup/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './src/executors/rollup/schema';
|
||||
export * from './src/executors/rollup/rollup.impl';
|
||||
11
packages/rollup/jest.config.ts
Normal file
11
packages/rollup/jest.config.ts
Normal file
@ -0,0 +1,11 @@
|
||||
/* eslint-disable */
|
||||
export default {
|
||||
transform: {
|
||||
'^.+\\.[tj]sx?$': 'ts-jest',
|
||||
},
|
||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
|
||||
globals: { 'ts-jest': { tsconfig: '<rootDir>/tsconfig.spec.json' } },
|
||||
displayName: 'rollup',
|
||||
testEnvironment: 'node',
|
||||
preset: '../../jest.preset.js',
|
||||
};
|
||||
52
packages/rollup/package.json
Normal file
52
packages/rollup/package.json
Normal file
@ -0,0 +1,52 @@
|
||||
{
|
||||
"name": "@nrwl/rollup",
|
||||
"version": "0.0.1",
|
||||
"description": "The Nx Plugin for Rollup contains executors and generators that support building applications using Rollup",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nrwl/nx.git",
|
||||
"directory": "packages/rollup"
|
||||
},
|
||||
"keywords": [
|
||||
"Monorepo",
|
||||
"Rollup",
|
||||
"Web",
|
||||
"CLI"
|
||||
],
|
||||
"main": "./index.js",
|
||||
"typings": "./index.d.ts",
|
||||
"author": "Victor Savkin",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/nrwl/nx/issues"
|
||||
},
|
||||
"homepage": "https://nx.dev",
|
||||
"schematics": "./generators.json",
|
||||
"builders": "./executors.json",
|
||||
"ng-update": {
|
||||
"requirements": {},
|
||||
"migrations": "./migrations.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nrwl/devkit": "file:../devkit",
|
||||
"@nrwl/js": "file:../js",
|
||||
"@nrwl/workspace": "file:../workspace",
|
||||
"@rollup/plugin-babel": "^5.3.0",
|
||||
"@rollup/plugin-commonjs": "^20.0.0",
|
||||
"@rollup/plugin-image": "^2.1.0",
|
||||
"@rollup/plugin-json": "^4.1.0",
|
||||
"@rollup/plugin-node-resolve": "^13.0.4",
|
||||
"autoprefixer": "^10.4.9",
|
||||
"babel-plugin-transform-async-to-promises": "^0.8.15",
|
||||
"chalk": "4.1.0",
|
||||
"fs-extra": "^10.1.0",
|
||||
"postcss": "^8.4.14",
|
||||
"rollup": "^2.56.2",
|
||||
"rollup-plugin-copy": "^3.4.0",
|
||||
"rollup-plugin-peer-deps-external": "^2.2.4",
|
||||
"rollup-plugin-postcss": "^4.0.1",
|
||||
"rollup-plugin-typescript2": "^0.31.1",
|
||||
"rxjs": "^6.5.4",
|
||||
"tslib": "^2.3.0"
|
||||
}
|
||||
}
|
||||
87
packages/rollup/project.json
Normal file
87
packages/rollup/project.json
Normal file
@ -0,0 +1,87 @@
|
||||
{
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "packages/rollup",
|
||||
"projectType": "library",
|
||||
"targets": {
|
||||
"test": {
|
||||
"executor": "@nrwl/jest:jest",
|
||||
"options": {
|
||||
"jestConfig": "packages/rollup/jest.config.ts",
|
||||
"passWithNoTests": true
|
||||
},
|
||||
"outputs": ["coverage/packages/rollup"]
|
||||
},
|
||||
"build-base": {
|
||||
"executor": "@nrwl/js:tsc",
|
||||
"options": {
|
||||
"outputPath": "build/packages/rollup",
|
||||
"tsConfig": "packages/rollup/tsconfig.lib.json",
|
||||
"main": "packages/rollup/index.ts",
|
||||
"updateBuildableProjectDepsInPackageJson": false,
|
||||
"assets": [
|
||||
{
|
||||
"input": "packages/rollup",
|
||||
"glob": "**/files/**",
|
||||
"output": "/"
|
||||
},
|
||||
{
|
||||
"input": "packages/rollup",
|
||||
"glob": "**/files/**/.gitkeep",
|
||||
"output": "/"
|
||||
},
|
||||
{
|
||||
"input": "packages/rollup",
|
||||
"glob": "**/*.json",
|
||||
"ignore": ["**/tsconfig*.json", "project.json", ".eslintrc.json"],
|
||||
"output": "/"
|
||||
},
|
||||
{
|
||||
"input": "packages/rollup",
|
||||
"glob": "**/*.js",
|
||||
"ignore": ["**/jest.config.js"],
|
||||
"output": "/"
|
||||
},
|
||||
{
|
||||
"input": "packages/rollup",
|
||||
"glob": "**/*.d.ts",
|
||||
"output": "/"
|
||||
},
|
||||
{
|
||||
"input": "",
|
||||
"glob": "LICENSE",
|
||||
"output": "/"
|
||||
}
|
||||
]
|
||||
},
|
||||
"outputs": ["{options.outputPath}"]
|
||||
},
|
||||
"build": {
|
||||
"executor": "nx:run-commands",
|
||||
"outputs": ["build/packages/rollup"],
|
||||
"options": {
|
||||
"command": "node ./scripts/copy-readme.js rollup"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nrwl/linter:eslint",
|
||||
"options": {
|
||||
"lintFilePatterns": [
|
||||
"packages/rollup/**/*.ts",
|
||||
"packages/rollup/**/*.spec.ts",
|
||||
"packages/rollup/**/*_spec.ts",
|
||||
"packages/rollup/**/*.spec.tsx",
|
||||
"packages/rollup/**/*.spec.js",
|
||||
"packages/rollup/**/*.spec.jsx",
|
||||
"packages/rollup/**/*.d.ts",
|
||||
"packages/rollup/**/executors/**/schema.json",
|
||||
"packages/rollup/**/generators/**/schema.json",
|
||||
"packages/rollup/generators.json",
|
||||
"packages/rollup/executors.json",
|
||||
"packages/rollup/package.json",
|
||||
"packages/rollup/migrations.json"
|
||||
]
|
||||
},
|
||||
"outputs": ["{options.outputFile}"]
|
||||
}
|
||||
}
|
||||
}
|
||||
5
packages/rollup/src/executors/rollup/compat.ts
Normal file
5
packages/rollup/src/executors/rollup/compat.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { convertNxExecutor } from '@nrwl/devkit';
|
||||
|
||||
import rollupExecutor from './rollup.impl';
|
||||
|
||||
export default convertNxExecutor(rollupExecutor);
|
||||
@ -1,8 +1,8 @@
|
||||
import { normalizeWebRollupOptions } from './normalize';
|
||||
import { WebRollupOptions } from '../schema';
|
||||
import { normalizeRollupExecutorOptions } from './normalize';
|
||||
import { RollupExecutorOptions } from '../schema';
|
||||
|
||||
describe('normalizeWebRollupOptions', () => {
|
||||
let testOptions: WebRollupOptions;
|
||||
describe('normalizeRollupExecutorOptions', () => {
|
||||
let testOptions: RollupExecutorOptions;
|
||||
let root: string;
|
||||
let sourceRoot: string;
|
||||
|
||||
@ -10,7 +10,7 @@ describe('normalizeWebRollupOptions', () => {
|
||||
testOptions = {
|
||||
outputPath: '/tmp',
|
||||
project: 'apps/nodeapp/package.json',
|
||||
entryFile: 'apps/nodeapp/src/main.ts',
|
||||
main: 'apps/nodeapp/src/main.ts',
|
||||
tsConfig: 'apps/nodeapp/tsconfig.app.json',
|
||||
rollupConfig: 'apps/nodeapp/rollup.config',
|
||||
format: ['esm'],
|
||||
@ -20,10 +20,10 @@ describe('normalizeWebRollupOptions', () => {
|
||||
});
|
||||
|
||||
it('should resolve both node modules and relative path for rollupConfig', () => {
|
||||
let result = normalizeWebRollupOptions(testOptions, root, sourceRoot);
|
||||
let result = normalizeRollupExecutorOptions(testOptions, root, sourceRoot);
|
||||
expect(result.rollupConfig).toEqual(['/root/apps/nodeapp/rollup.config']);
|
||||
|
||||
result = normalizeWebRollupOptions(
|
||||
result = normalizeRollupExecutorOptions(
|
||||
{
|
||||
...testOptions,
|
||||
// something that exists in node_modules
|
||||
@ -40,7 +40,11 @@ describe('normalizeWebRollupOptions', () => {
|
||||
it('should handle rollupConfig being undefined', () => {
|
||||
delete testOptions.rollupConfig;
|
||||
|
||||
const result = normalizeWebRollupOptions(testOptions, root, sourceRoot);
|
||||
const result = normalizeRollupExecutorOptions(
|
||||
testOptions,
|
||||
root,
|
||||
sourceRoot
|
||||
);
|
||||
expect(result.rollupConfig).toEqual([]);
|
||||
});
|
||||
});
|
||||
104
packages/rollup/src/executors/rollup/lib/normalize.ts
Normal file
104
packages/rollup/src/executors/rollup/lib/normalize.ts
Normal file
@ -0,0 +1,104 @@
|
||||
import { basename, dirname, relative, resolve } from 'path';
|
||||
import { statSync } from 'fs';
|
||||
import { normalizePath } from '@nrwl/devkit';
|
||||
|
||||
import type { AssetGlobPattern, RollupExecutorOptions } from '../schema';
|
||||
|
||||
export interface NormalizedRollupExecutorOptions extends RollupExecutorOptions {
|
||||
entryRoot: string;
|
||||
projectRoot: string;
|
||||
assets: AssetGlobPattern[];
|
||||
rollupConfig: string[];
|
||||
}
|
||||
|
||||
export function normalizeRollupExecutorOptions(
|
||||
options: RollupExecutorOptions,
|
||||
root: string,
|
||||
sourceRoot: string
|
||||
): NormalizedRollupExecutorOptions {
|
||||
const main = `${root}/${options.main}`;
|
||||
const entryRoot = dirname(main);
|
||||
const project = `${root}/${options.project}`;
|
||||
const projectRoot = dirname(project);
|
||||
const outputPath = `${root}/${options.outputPath}`;
|
||||
|
||||
if (options.buildableProjectDepsInPackageJsonType == undefined) {
|
||||
options.buildableProjectDepsInPackageJsonType = 'peerDependencies';
|
||||
}
|
||||
|
||||
return {
|
||||
...options,
|
||||
// de-dupe formats
|
||||
format: Array.from(new Set(options.format)),
|
||||
rollupConfig: []
|
||||
.concat(options.rollupConfig)
|
||||
.filter(Boolean)
|
||||
.map((p) => normalizePluginPath(p, root)),
|
||||
assets: options.assets
|
||||
? normalizeAssets(options.assets, root, sourceRoot)
|
||||
: undefined,
|
||||
main,
|
||||
entryRoot,
|
||||
project,
|
||||
projectRoot,
|
||||
outputPath,
|
||||
};
|
||||
}
|
||||
|
||||
export function normalizePluginPath(pluginPath: void | string, root: string) {
|
||||
if (!pluginPath) {
|
||||
return '';
|
||||
}
|
||||
try {
|
||||
return require.resolve(pluginPath);
|
||||
} catch {
|
||||
return resolve(root, pluginPath);
|
||||
}
|
||||
}
|
||||
|
||||
export function normalizeAssets(
|
||||
assets: any[],
|
||||
root: string,
|
||||
sourceRoot: string
|
||||
): AssetGlobPattern[] {
|
||||
return assets.map((asset) => {
|
||||
if (typeof asset === 'string') {
|
||||
const assetPath = normalizePath(asset);
|
||||
const resolvedAssetPath = resolve(root, assetPath);
|
||||
const resolvedSourceRoot = resolve(root, sourceRoot);
|
||||
|
||||
if (!resolvedAssetPath.startsWith(resolvedSourceRoot)) {
|
||||
throw new Error(
|
||||
`The ${resolvedAssetPath} asset path must start with the project source root: ${sourceRoot}`
|
||||
);
|
||||
}
|
||||
|
||||
const isDirectory = statSync(resolvedAssetPath).isDirectory();
|
||||
const input = isDirectory
|
||||
? resolvedAssetPath
|
||||
: dirname(resolvedAssetPath);
|
||||
const output = relative(resolvedSourceRoot, resolve(root, input));
|
||||
const glob = isDirectory ? '**/*' : basename(resolvedAssetPath);
|
||||
return {
|
||||
input,
|
||||
output,
|
||||
glob,
|
||||
};
|
||||
} else {
|
||||
if (asset.output.startsWith('..')) {
|
||||
throw new Error(
|
||||
'An asset cannot be written to a location outside of the output path.'
|
||||
);
|
||||
}
|
||||
|
||||
const assetPath = normalizePath(asset.input);
|
||||
const resolvedAssetPath = resolve(root, assetPath);
|
||||
return {
|
||||
...asset,
|
||||
input: resolvedAssetPath,
|
||||
// Now we remove starting slash to make Webpack place it from the output root.
|
||||
output: asset.output.replace(/^\//, ''),
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -7,7 +7,7 @@ describe('updatePackageJson', () => {
|
||||
outputPath: 'dist/index.js',
|
||||
tsConfig: './tsconfig.json',
|
||||
project: './package.json',
|
||||
entryFile: './index.js',
|
||||
main: './index.js',
|
||||
entryRoot: '.',
|
||||
projectRoot: '.',
|
||||
assets: [],
|
||||
@ -7,10 +7,10 @@ import {
|
||||
} from '@nrwl/workspace/src/utilities/buildable-libs-utils';
|
||||
import { writeJsonFile } from 'nx/src/utils/fileutils';
|
||||
import { PackageJson } from 'nx/src/utils/package-json';
|
||||
import { NormalizedWebRollupOptions } from './normalize';
|
||||
import { NormalizedRollupExecutorOptions } from './normalize';
|
||||
|
||||
export function updatePackageJson(
|
||||
options: NormalizedWebRollupOptions,
|
||||
options: NormalizedRollupExecutorOptions,
|
||||
context: ExecutorContext,
|
||||
target: ProjectGraphProjectNode,
|
||||
dependencies: DependentBuildableProjectNode[],
|
||||
@ -20,7 +20,7 @@ export function updatePackageJson(
|
||||
const hasCjsFormat =
|
||||
options.format.includes('umd') || options.format.includes('cjs');
|
||||
|
||||
const types = `./${relative(options.entryRoot, options.entryFile).replace(
|
||||
const types = `./${relative(options.entryRoot, options.main).replace(
|
||||
/\.[jt]sx?$/,
|
||||
'.d.ts'
|
||||
)}`;
|
||||
@ -1,14 +1,14 @@
|
||||
import { ExecutorContext } from '@nrwl/devkit';
|
||||
import * as rollup from 'rollup';
|
||||
import { WebRollupOptions } from './schema';
|
||||
import { RollupExecutorOptions } from './schema';
|
||||
import { createRollupOptions } from './rollup.impl';
|
||||
import { normalizeWebRollupOptions } from './lib/normalize';
|
||||
import { normalizeRollupExecutorOptions } from './lib/normalize';
|
||||
|
||||
jest.mock('rollup-plugin-copy', () => jest.fn());
|
||||
|
||||
describe('rollupExecutor', () => {
|
||||
let context: ExecutorContext;
|
||||
let testOptions: WebRollupOptions;
|
||||
let testOptions: RollupExecutorOptions;
|
||||
|
||||
beforeEach(async () => {
|
||||
context = {
|
||||
@ -25,7 +25,7 @@ describe('rollupExecutor', () => {
|
||||
};
|
||||
testOptions = {
|
||||
compiler: 'babel',
|
||||
entryFile: 'libs/ui/src/index.ts',
|
||||
main: 'libs/ui/src/index.ts',
|
||||
outputPath: 'dist/ui',
|
||||
project: 'libs/ui/package.json',
|
||||
tsConfig: 'libs/ui/tsconfig.json',
|
||||
@ -37,7 +37,7 @@ describe('rollupExecutor', () => {
|
||||
describe('createRollupOptions', () => {
|
||||
it('should create rollup options for valid config', () => {
|
||||
const result: any = createRollupOptions(
|
||||
normalizeWebRollupOptions(testOptions, '/root', '/root/src'),
|
||||
normalizeRollupExecutorOptions(testOptions, '/root', '/root/src'),
|
||||
[],
|
||||
context,
|
||||
{ name: 'example' },
|
||||
@ -74,7 +74,7 @@ describe('rollupExecutor', () => {
|
||||
{ virtual: true }
|
||||
);
|
||||
const result: any = createRollupOptions(
|
||||
normalizeWebRollupOptions(
|
||||
normalizeRollupExecutorOptions(
|
||||
{ ...testOptions, rollupConfig: 'custom-rollup.config.ts' },
|
||||
'/root',
|
||||
'/root/src'
|
||||
@ -104,7 +104,7 @@ describe('rollupExecutor', () => {
|
||||
{ virtual: true }
|
||||
);
|
||||
const result: any = createRollupOptions(
|
||||
normalizeWebRollupOptions(
|
||||
normalizeRollupExecutorOptions(
|
||||
{
|
||||
...testOptions,
|
||||
rollupConfig: [
|
||||
@ -131,7 +131,7 @@ describe('rollupExecutor', () => {
|
||||
it(`should always use forward slashes for asset paths`, () => {
|
||||
createRollupOptions(
|
||||
{
|
||||
...normalizeWebRollupOptions(testOptions, '/root', '/root/src'),
|
||||
...normalizeRollupExecutorOptions(testOptions, '/root', '/root/src'),
|
||||
assets: [
|
||||
{
|
||||
glob: 'README.md',
|
||||
@ -154,7 +154,7 @@ describe('rollupExecutor', () => {
|
||||
|
||||
it(`should treat npm dependencies as external`, () => {
|
||||
const options = createRollupOptions(
|
||||
normalizeWebRollupOptions(testOptions, '/root', '/root/src'),
|
||||
normalizeRollupExecutorOptions(testOptions, '/root', '/root/src'),
|
||||
[],
|
||||
context,
|
||||
{ name: 'example' },
|
||||
367
packages/rollup/src/executors/rollup/rollup.impl.ts
Normal file
367
packages/rollup/src/executors/rollup/rollup.impl.ts
Normal file
@ -0,0 +1,367 @@
|
||||
import * as ts from 'typescript';
|
||||
import * as rollup from 'rollup';
|
||||
import * as peerDepsExternal from 'rollup-plugin-peer-deps-external';
|
||||
import { getBabelInputPlugin } from '@rollup/plugin-babel';
|
||||
import { dirname, join, parse } from 'path';
|
||||
import { from, Observable, of } from 'rxjs';
|
||||
import { catchError, concatMap, last, scan, tap } from 'rxjs/operators';
|
||||
import { eachValueFrom } from '@nrwl/devkit/src/utils/rxjs-for-await';
|
||||
import * as autoprefixer from 'autoprefixer';
|
||||
import type { ExecutorContext } from '@nrwl/devkit';
|
||||
import { joinPathFragments, logger, names, readJsonFile } from '@nrwl/devkit';
|
||||
import {
|
||||
calculateProjectDependencies,
|
||||
computeCompilerOptionsPaths,
|
||||
DependentBuildableProjectNode,
|
||||
} from '@nrwl/workspace/src/utilities/buildable-libs-utils';
|
||||
import resolve from '@rollup/plugin-node-resolve';
|
||||
|
||||
import { AssetGlobPattern, RollupExecutorOptions } from './schema';
|
||||
import { runRollup } from './lib/run-rollup';
|
||||
import {
|
||||
NormalizedRollupExecutorOptions,
|
||||
normalizeRollupExecutorOptions,
|
||||
} from './lib/normalize';
|
||||
import { analyze } from './lib/analyze-plugin';
|
||||
import { deleteOutputDir } from '../../utils/fs';
|
||||
import { swc } from './lib/swc-plugin';
|
||||
import { validateTypes } from './lib/validate-types';
|
||||
import { updatePackageJson } from './lib/update-package-json';
|
||||
|
||||
// These use require because the ES import isn't correct.
|
||||
const commonjs = require('@rollup/plugin-commonjs');
|
||||
const image = require('@rollup/plugin-image');
|
||||
|
||||
const json = require('@rollup/plugin-json');
|
||||
const copy = require('rollup-plugin-copy');
|
||||
const postcss = require('rollup-plugin-postcss');
|
||||
|
||||
const fileExtensions = ['.js', '.jsx', '.ts', '.tsx'];
|
||||
|
||||
export async function* rollupExecutor(
|
||||
rawOptions: RollupExecutorOptions,
|
||||
context: ExecutorContext
|
||||
) {
|
||||
process.env.NODE_ENV ??= 'production';
|
||||
|
||||
const project = context.workspace.projects[context.projectName];
|
||||
const sourceRoot = project.sourceRoot;
|
||||
const { target, dependencies } = calculateProjectDependencies(
|
||||
context.projectGraph,
|
||||
context.root,
|
||||
context.projectName,
|
||||
context.targetName,
|
||||
context.configurationName,
|
||||
true
|
||||
);
|
||||
|
||||
const options = normalizeRollupExecutorOptions(
|
||||
rawOptions,
|
||||
context.root,
|
||||
sourceRoot
|
||||
);
|
||||
|
||||
// TODO(jack): Remove UMD in Nx 15
|
||||
if (options.format.includes('umd')) {
|
||||
if (options.format.includes('cjs')) {
|
||||
throw new Error(
|
||||
'Cannot use both UMD and CJS. We recommend you use ESM or CJS.'
|
||||
);
|
||||
} else {
|
||||
logger.warn('UMD format is deprecated and will be removed in Nx 15');
|
||||
}
|
||||
}
|
||||
const packageJson = readJsonFile(options.project);
|
||||
|
||||
const npmDeps = (context.projectGraph.dependencies[context.projectName] ?? [])
|
||||
.filter((d) => d.target.startsWith('npm:'))
|
||||
.map((d) => d.target.slice(4));
|
||||
|
||||
const rollupOptions = createRollupOptions(
|
||||
options,
|
||||
dependencies,
|
||||
context,
|
||||
packageJson,
|
||||
sourceRoot,
|
||||
npmDeps
|
||||
);
|
||||
|
||||
if (options.compiler === 'swc') {
|
||||
try {
|
||||
await validateTypes({
|
||||
workspaceRoot: context.root,
|
||||
projectRoot: options.projectRoot,
|
||||
tsconfig: options.tsConfig,
|
||||
});
|
||||
} catch {
|
||||
return { success: false };
|
||||
}
|
||||
}
|
||||
|
||||
if (options.watch) {
|
||||
const watcher = rollup.watch(rollupOptions);
|
||||
return yield* eachValueFrom(
|
||||
new Observable<{ success: boolean }>((obs) => {
|
||||
watcher.on('event', (data) => {
|
||||
if (data.code === 'START') {
|
||||
logger.info(`Bundling ${context.projectName}...`);
|
||||
} else if (data.code === 'END') {
|
||||
updatePackageJson(
|
||||
options,
|
||||
context,
|
||||
target,
|
||||
dependencies,
|
||||
packageJson
|
||||
);
|
||||
logger.info('Bundle complete. Watching for file changes...');
|
||||
obs.next({ success: true });
|
||||
} else if (data.code === 'ERROR') {
|
||||
logger.error(`Error during bundle: ${data.error.message}`);
|
||||
obs.next({ success: false });
|
||||
}
|
||||
});
|
||||
// Teardown logic. Close watcher when unsubscribed.
|
||||
return () => watcher.close();
|
||||
})
|
||||
);
|
||||
} else {
|
||||
logger.info(`Bundling ${context.projectName}...`);
|
||||
|
||||
// Delete output path before bundling
|
||||
if (options.deleteOutputPath) {
|
||||
deleteOutputDir(context.root, options.outputPath);
|
||||
}
|
||||
|
||||
const start = process.hrtime.bigint();
|
||||
|
||||
return from(rollupOptions)
|
||||
.pipe(
|
||||
concatMap((opts) =>
|
||||
runRollup(opts).pipe(
|
||||
catchError((e) => {
|
||||
logger.error(`Error during bundle: ${e}`);
|
||||
return of({ success: false });
|
||||
})
|
||||
)
|
||||
),
|
||||
scan(
|
||||
(acc, result) => {
|
||||
if (!acc.success) return acc;
|
||||
return result;
|
||||
},
|
||||
{ success: true }
|
||||
),
|
||||
last(),
|
||||
tap({
|
||||
next: (result) => {
|
||||
if (result.success) {
|
||||
const end = process.hrtime.bigint();
|
||||
const duration = `${(Number(end - start) / 1_000_000_000).toFixed(
|
||||
2
|
||||
)}s`;
|
||||
|
||||
updatePackageJson(
|
||||
options,
|
||||
context,
|
||||
target,
|
||||
dependencies,
|
||||
packageJson
|
||||
);
|
||||
logger.info(`⚡ Done in ${duration}`);
|
||||
} else {
|
||||
logger.error(`Bundle failed: ${context.projectName}`);
|
||||
}
|
||||
},
|
||||
})
|
||||
)
|
||||
.toPromise();
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
export function createRollupOptions(
|
||||
options: NormalizedRollupExecutorOptions,
|
||||
dependencies: DependentBuildableProjectNode[],
|
||||
context: ExecutorContext,
|
||||
packageJson: any,
|
||||
sourceRoot: string,
|
||||
npmDeps: string[]
|
||||
): rollup.InputOptions[] {
|
||||
const useBabel = options.compiler === 'babel';
|
||||
const useTsc = options.compiler === 'tsc';
|
||||
const useSwc = options.compiler === 'swc';
|
||||
|
||||
const tsConfigPath = joinPathFragments(context.root, options.tsConfig);
|
||||
const configFile = ts.readConfigFile(tsConfigPath, ts.sys.readFile);
|
||||
const config = ts.parseJsonConfigFileContent(
|
||||
configFile.config,
|
||||
ts.sys,
|
||||
dirname(tsConfigPath)
|
||||
);
|
||||
|
||||
if (!options.format || !options.format.length) {
|
||||
options.format = readCompatibleFormats(config);
|
||||
}
|
||||
|
||||
return options.format.map((format, idx) => {
|
||||
const plugins = [
|
||||
copy({
|
||||
targets: convertCopyAssetsToRollupOptions(
|
||||
options.outputPath,
|
||||
options.assets
|
||||
),
|
||||
}),
|
||||
image(),
|
||||
json(),
|
||||
(useTsc || useBabel) &&
|
||||
require('rollup-plugin-typescript2')({
|
||||
check: true,
|
||||
tsconfig: options.tsConfig,
|
||||
tsconfigOverride: {
|
||||
compilerOptions: createTsCompilerOptions(
|
||||
config,
|
||||
dependencies,
|
||||
options
|
||||
),
|
||||
},
|
||||
}),
|
||||
peerDepsExternal({
|
||||
packageJsonPath: options.project,
|
||||
}),
|
||||
postcss({
|
||||
inject: true,
|
||||
extract: options.extractCss,
|
||||
autoModules: true,
|
||||
plugins: [autoprefixer],
|
||||
use: {
|
||||
less: {
|
||||
javascriptEnabled: options.javascriptEnabled,
|
||||
},
|
||||
},
|
||||
}),
|
||||
resolve({
|
||||
preferBuiltins: true,
|
||||
extensions: fileExtensions,
|
||||
}),
|
||||
useSwc && swc(),
|
||||
useBabel &&
|
||||
getBabelInputPlugin({
|
||||
// Let's `@nrwl/web/babel` preset know that we are packaging.
|
||||
caller: {
|
||||
// @ts-ignore
|
||||
// Ignoring type checks for caller since we have custom attributes
|
||||
isNxPackage: true,
|
||||
// Always target esnext and let rollup handle cjs/umd
|
||||
supportsStaticESM: true,
|
||||
isModern: true,
|
||||
},
|
||||
cwd: join(context.root, sourceRoot),
|
||||
rootMode: 'upward',
|
||||
babelrc: true,
|
||||
extensions: fileExtensions,
|
||||
babelHelpers: 'bundled',
|
||||
skipPreflightCheck: true, // pre-flight check may yield false positives and also slows down the build
|
||||
exclude: /node_modules/,
|
||||
plugins: [
|
||||
format === 'esm'
|
||||
? undefined
|
||||
: require.resolve('babel-plugin-transform-async-to-promises'),
|
||||
].filter(Boolean),
|
||||
}),
|
||||
commonjs(),
|
||||
analyze(),
|
||||
];
|
||||
|
||||
const globals = options.globals
|
||||
? options.globals.reduce(
|
||||
(acc, item) => {
|
||||
acc[item.moduleId] = item.global;
|
||||
return acc;
|
||||
},
|
||||
{ 'react/jsx-runtime': 'jsxRuntime' }
|
||||
)
|
||||
: { 'react/jsx-runtime': 'jsxRuntime' };
|
||||
|
||||
const externalPackages = dependencies
|
||||
.map((d) => d.name)
|
||||
.concat(options.external || [])
|
||||
.concat(Object.keys(packageJson.dependencies || {}));
|
||||
|
||||
const rollupConfig = {
|
||||
input: options.outputFileName
|
||||
? {
|
||||
[parse(options.outputFileName).name]: options.main,
|
||||
}
|
||||
: options.main,
|
||||
output: {
|
||||
globals,
|
||||
format,
|
||||
dir: `${options.outputPath}`,
|
||||
name: options.umdName || names(context.projectName).className,
|
||||
entryFileNames: `[name].${format === 'esm' ? 'js' : 'cjs'}`,
|
||||
chunkFileNames: `[name].${format === 'esm' ? 'js' : 'cjs'}`,
|
||||
// umd doesn't support code-split bundles
|
||||
inlineDynamicImports: format === 'umd',
|
||||
},
|
||||
external: (id) =>
|
||||
externalPackages.some(
|
||||
(name) => id === name || id.startsWith(`${name}/`)
|
||||
) || npmDeps.some((name) => id === name || id.startsWith(`${name}/`)), // Could be a deep import
|
||||
plugins,
|
||||
};
|
||||
|
||||
return options.rollupConfig.reduce((currentConfig, plugin) => {
|
||||
return require(plugin)(currentConfig, options);
|
||||
}, rollupConfig);
|
||||
});
|
||||
}
|
||||
|
||||
function createTsCompilerOptions(
|
||||
config: ts.ParsedCommandLine,
|
||||
dependencies,
|
||||
options
|
||||
) {
|
||||
const compilerOptionPaths = computeCompilerOptionsPaths(config, dependencies);
|
||||
const compilerOptions = {
|
||||
rootDir: options.entryRoot,
|
||||
allowJs: false,
|
||||
declaration: true,
|
||||
paths: compilerOptionPaths,
|
||||
};
|
||||
if (config.options.module === ts.ModuleKind.CommonJS) {
|
||||
compilerOptions['module'] = 'ESNext';
|
||||
}
|
||||
return compilerOptions;
|
||||
}
|
||||
|
||||
interface RollupCopyAssetOption {
|
||||
src: string;
|
||||
dest: string;
|
||||
}
|
||||
|
||||
function convertCopyAssetsToRollupOptions(
|
||||
outputPath: string,
|
||||
assets: AssetGlobPattern[]
|
||||
): RollupCopyAssetOption[] {
|
||||
return assets
|
||||
? assets.map((a) => ({
|
||||
src: join(a.input, a.glob).replace(/\\/g, '/'),
|
||||
dest: join(outputPath, a.output).replace(/\\/g, '/'),
|
||||
}))
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function readCompatibleFormats(config: ts.ParsedCommandLine) {
|
||||
switch (config.options.module) {
|
||||
case ts.ModuleKind.CommonJS:
|
||||
return ['cjs'];
|
||||
case ts.ModuleKind.UMD:
|
||||
case ts.ModuleKind.AMD:
|
||||
return ['umd'];
|
||||
default:
|
||||
return ['esm'];
|
||||
}
|
||||
}
|
||||
|
||||
export default rollupExecutor;
|
||||
37
packages/rollup/src/executors/rollup/schema.d.ts
vendored
Normal file
37
packages/rollup/src/executors/rollup/schema.d.ts
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
type Compiler = 'babel' | 'swc';
|
||||
|
||||
export interface AssetGlobPattern {
|
||||
glob: string;
|
||||
input: string;
|
||||
output: string;
|
||||
ignore?: string[];
|
||||
}
|
||||
|
||||
export interface Globals {
|
||||
moduleId: string;
|
||||
global: string;
|
||||
}
|
||||
|
||||
export interface RollupExecutorOptions {
|
||||
outputPath: string;
|
||||
tsConfig: string;
|
||||
project: string;
|
||||
main: string;
|
||||
outputFileName?: string;
|
||||
extractCss?: boolean | string;
|
||||
globals?: Globals[];
|
||||
external?: string[];
|
||||
rollupConfig?: string | string[];
|
||||
watch?: boolean;
|
||||
assets?: any[];
|
||||
updateBuildableProjectDepsInPackageJson?: boolean;
|
||||
buildableProjectDepsInPackageJsonType?: 'dependencies' | 'peerDependencies';
|
||||
umdName?: string;
|
||||
deleteOutputPath?: boolean;
|
||||
format?: string[];
|
||||
compiler?: 'babel' | 'tsc' | 'swc';
|
||||
javascriptEnabled?: boolean;
|
||||
// TODO(jack): remove this for Nx 15
|
||||
skipTypeField?: boolean;
|
||||
generateExportsField?: boolean;
|
||||
}
|
||||
176
packages/rollup/src/executors/rollup/schema.json
Normal file
176
packages/rollup/src/executors/rollup/schema.json
Normal file
@ -0,0 +1,176 @@
|
||||
{
|
||||
"title": "Web Library Rollup Target (Experimental)",
|
||||
"description": "Packages a library for different web usages (`UMD`, `ESM`, `CJS`).",
|
||||
"cli": "nx",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"project": {
|
||||
"type": "string",
|
||||
"description": "The path to package.json file."
|
||||
},
|
||||
"main": {
|
||||
"type": "string",
|
||||
"description": "The path to the entry file, relative to project.",
|
||||
"alias": "entryFile",
|
||||
"x-completion-type": "file",
|
||||
"x-completion-glob": "**/*@(.js|.ts)"
|
||||
},
|
||||
"outputPath": {
|
||||
"type": "string",
|
||||
"description": "The output path of the generated files.",
|
||||
"x-completion-type": "directory"
|
||||
},
|
||||
"outputFileName": {
|
||||
"type": "string",
|
||||
"description": "Name of the main output file. Defaults same basename as 'main' file."
|
||||
},
|
||||
"deleteOutputPath": {
|
||||
"type": "boolean",
|
||||
"description": "Delete the output path before building.",
|
||||
"default": true
|
||||
},
|
||||
"tsConfig": {
|
||||
"type": "string",
|
||||
"description": "The path to tsconfig file.",
|
||||
"x-completion-type": "file",
|
||||
"x-completion-glob": "tsconfig.*.json"
|
||||
},
|
||||
"format": {
|
||||
"type": "array",
|
||||
"description": "List of module formats to output. Defaults to matching format from tsconfig (e.g. CJS for CommonJS, and ESM otherwise).",
|
||||
"alias": "f",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": ["esm", "umd", "cjs"]
|
||||
}
|
||||
},
|
||||
"external": {
|
||||
"type": "array",
|
||||
"description": "A list of external modules that will not be bundled (`react`, `react-dom`, etc.).",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"watch": {
|
||||
"type": "boolean",
|
||||
"description": "Enable re-building when files change.",
|
||||
"default": false
|
||||
},
|
||||
"updateBuildableProjectDepsInPackageJson": {
|
||||
"type": "boolean",
|
||||
"description": "Update buildable project dependencies in `package.json`.",
|
||||
"default": true
|
||||
},
|
||||
"buildableProjectDepsInPackageJsonType": {
|
||||
"type": "string",
|
||||
"description": "When `updateBuildableProjectDepsInPackageJson` is `true`, this adds dependencies to either `peerDependencies` or `dependencies`.",
|
||||
"enum": ["dependencies", "peerDependencies"],
|
||||
"default": "peerDependencies"
|
||||
},
|
||||
"rollupConfig": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"x-completion-type": "file",
|
||||
"x-completion-glob": "rollup?(*)@(.js|.ts)"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"x-completion-type": "file",
|
||||
"x-completion-glob": "rollup?(*)@(.js|.ts)"
|
||||
}
|
||||
],
|
||||
"description": "Path to a function which takes a rollup config and returns an updated rollup config."
|
||||
},
|
||||
"umdName": {
|
||||
"type": "string",
|
||||
"description": "The name of your module in `UMD` format. Defaulted to your project name."
|
||||
},
|
||||
"globals": {
|
||||
"description": "A mapping of node modules to their `UMD` global names. Used by the `UMD` bundle.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"moduleId": {
|
||||
"type": "string",
|
||||
"description": "The node module to map from (e.g. `react-dom`)."
|
||||
},
|
||||
"global": {
|
||||
"type": "string",
|
||||
"description": "The global name to map to (e.g. `ReactDOM`)."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["moduleId", "global"]
|
||||
},
|
||||
"default": []
|
||||
},
|
||||
"extractCss": {
|
||||
"type": ["boolean", "string"],
|
||||
"description": "CSS files will be extracted to the output folder. Alternatively custom filename can be provided (e.g. styles.css)",
|
||||
"default": true
|
||||
},
|
||||
"assets": {
|
||||
"type": "array",
|
||||
"description": "List of static assets.",
|
||||
"default": [],
|
||||
"items": {
|
||||
"$ref": "#/definitions/assetPattern"
|
||||
}
|
||||
},
|
||||
"compiler": {
|
||||
"type": "string",
|
||||
"enum": ["babel", "swc", "tsc"],
|
||||
"default": "babel",
|
||||
"description": "Which compiler to use."
|
||||
},
|
||||
"javascriptEnabled": {
|
||||
"type": "boolean",
|
||||
"description": "Sets `javascriptEnabled` option for less loader",
|
||||
"default": false
|
||||
},
|
||||
"generateExportsField": {
|
||||
"type": "boolean",
|
||||
"description": "Generate package.json with 'exports' field. This field defines entry points in the package and is used by Node and the TypeScript compiler.",
|
||||
"default": false
|
||||
},
|
||||
"skipTypeField": {
|
||||
"type": "boolean",
|
||||
"description": "Prevents 'type' field from being added to compiled package.json file. Only use this if you are having an issue with this field.",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"required": ["tsConfig", "project", "main", "outputPath"],
|
||||
"definitions": {
|
||||
"assetPattern": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"glob": {
|
||||
"type": "string",
|
||||
"description": "The pattern to match."
|
||||
},
|
||||
"input": {
|
||||
"type": "string",
|
||||
"description": "The input directory path in which to apply `glob`. Defaults to the project root."
|
||||
},
|
||||
"output": {
|
||||
"type": "string",
|
||||
"description": "Relative path within the output folder."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["glob", "input", "output"]
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
57
packages/rollup/src/generators/init/init.spec.ts
Normal file
57
packages/rollup/src/generators/init/init.spec.ts
Normal file
@ -0,0 +1,57 @@
|
||||
import { Tree, readJson, NxJsonConfiguration, updateJson } from '@nrwl/devkit';
|
||||
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
|
||||
|
||||
import { rollupInitGenerator } from './init';
|
||||
|
||||
describe('rollupInitGenerator', () => {
|
||||
let tree: Tree;
|
||||
|
||||
beforeEach(async () => {
|
||||
tree = createTreeWithEmptyWorkspace();
|
||||
});
|
||||
|
||||
it('should support babel', async () => {
|
||||
updateJson<NxJsonConfiguration>(tree, 'nx.json', (json) => {
|
||||
json.namedInputs = {
|
||||
sharedGlobals: ['{workspaceRoot}/exiting-file.json'],
|
||||
};
|
||||
return json;
|
||||
});
|
||||
|
||||
await rollupInitGenerator(tree, { compiler: 'babel' });
|
||||
|
||||
expect(tree.exists('babel.config.json'));
|
||||
const sharedGlobals = readJson<NxJsonConfiguration>(tree, 'nx.json')
|
||||
.namedInputs.sharedGlobals;
|
||||
expect(sharedGlobals).toContain('{workspaceRoot}/exiting-file.json');
|
||||
expect(sharedGlobals).toContain('{workspaceRoot}/babel.config.json');
|
||||
});
|
||||
|
||||
it('should support swc', async () => {
|
||||
await rollupInitGenerator(tree, { compiler: 'swc' });
|
||||
|
||||
const packageJson = readJson(tree, 'package.json');
|
||||
expect(packageJson).toEqual({
|
||||
name: expect.any(String),
|
||||
dependencies: {},
|
||||
devDependencies: {
|
||||
'@swc/helpers': expect.any(String),
|
||||
'@swc/core': expect.any(String),
|
||||
'swc-loader': expect.any(String),
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should support tsc', async () => {
|
||||
await rollupInitGenerator(tree, { compiler: 'tsc' });
|
||||
|
||||
const packageJson = readJson(tree, 'package.json');
|
||||
expect(packageJson).toEqual({
|
||||
name: expect.any(String),
|
||||
dependencies: {},
|
||||
devDependencies: {
|
||||
tslib: expect.any(String),
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
66
packages/rollup/src/generators/init/init.ts
Normal file
66
packages/rollup/src/generators/init/init.ts
Normal file
@ -0,0 +1,66 @@
|
||||
import {
|
||||
addDependenciesToPackageJson,
|
||||
convertNxGenerator,
|
||||
formatFiles,
|
||||
GeneratorCallback,
|
||||
readWorkspaceConfiguration,
|
||||
Tree,
|
||||
updateWorkspaceConfiguration,
|
||||
writeJson,
|
||||
} from '@nrwl/devkit';
|
||||
import { Schema } from './schema';
|
||||
import { swcCoreVersion, swcHelpersVersion } from '@nrwl/js/src/utils/versions';
|
||||
import { swcLoaderVersion, tsLibVersion } from '../../utils/versions';
|
||||
|
||||
export async function rollupInitGenerator(tree: Tree, schema: Schema) {
|
||||
let task: GeneratorCallback;
|
||||
|
||||
if (schema.compiler === 'babel') {
|
||||
initRootBabelConfig(tree);
|
||||
}
|
||||
|
||||
if (schema.compiler === 'swc') {
|
||||
task = addDependenciesToPackageJson(
|
||||
tree,
|
||||
{},
|
||||
{
|
||||
'@swc/helpers': swcHelpersVersion,
|
||||
'@swc/core': swcCoreVersion,
|
||||
'swc-loader': swcLoaderVersion,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (schema.compiler === 'tsc') {
|
||||
task = addDependenciesToPackageJson(tree, {}, { tslib: tsLibVersion });
|
||||
}
|
||||
|
||||
if (!schema.skipFormat) {
|
||||
await formatFiles(tree);
|
||||
}
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
function initRootBabelConfig(tree: Tree) {
|
||||
if (tree.exists('/babel.config.json') || tree.exists('/babel.config.js')) {
|
||||
return;
|
||||
}
|
||||
|
||||
writeJson(tree, '/babel.config.json', {
|
||||
babelrcRoots: ['*'], // Make sure .babelrc files other than root can be loaded in a monorepo
|
||||
});
|
||||
|
||||
const workspaceConfiguration = readWorkspaceConfiguration(tree);
|
||||
|
||||
if (workspaceConfiguration.namedInputs?.sharedGlobals) {
|
||||
workspaceConfiguration.namedInputs.sharedGlobals.push(
|
||||
'{workspaceRoot}/babel.config.json'
|
||||
);
|
||||
}
|
||||
updateWorkspaceConfiguration(tree, workspaceConfiguration);
|
||||
}
|
||||
|
||||
export default rollupInitGenerator;
|
||||
|
||||
export const rollupInitSchematic = convertNxGenerator(rollupInitGenerator);
|
||||
4
packages/rollup/src/generators/init/schema.d.ts
vendored
Normal file
4
packages/rollup/src/generators/init/schema.d.ts
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
export interface Schema {
|
||||
compiler?: 'babel' | 'swc' | 'tsc';
|
||||
skipFormat?: boolean;
|
||||
}
|
||||
22
packages/rollup/src/generators/init/schema.json
Normal file
22
packages/rollup/src/generators/init/schema.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/schema",
|
||||
"$id": "NxWebpackInit",
|
||||
"cli": "nx",
|
||||
"title": "Init Webpack Plugin",
|
||||
"description": "Init Webpack Plugin.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"compiler": {
|
||||
"type": "string",
|
||||
"enum": ["babel", "swc", "tsc"],
|
||||
"description": "The compiler to initialize for.",
|
||||
"default": "babel"
|
||||
},
|
||||
"skipFormat": {
|
||||
"description": "Skip formatting files.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
@ -0,0 +1,102 @@
|
||||
import {
|
||||
addProjectConfiguration,
|
||||
readJson,
|
||||
readProjectConfiguration,
|
||||
Tree,
|
||||
writeJson,
|
||||
} from '@nrwl/devkit';
|
||||
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
|
||||
|
||||
import { rollupProjectGenerator } from './rollup-project';
|
||||
|
||||
describe('rollupProjectGenerator', () => {
|
||||
let tree: Tree;
|
||||
|
||||
beforeEach(async () => {
|
||||
tree = createTreeWithEmptyWorkspace();
|
||||
addProjectConfiguration(tree, 'mypkg', {
|
||||
root: 'libs/mypkg',
|
||||
sourceRoot: 'libs/mypkg/src',
|
||||
targets: {},
|
||||
});
|
||||
});
|
||||
|
||||
it('should generate files', async () => {
|
||||
await rollupProjectGenerator(tree, {
|
||||
project: 'mypkg',
|
||||
});
|
||||
|
||||
const project = readProjectConfiguration(tree, 'mypkg');
|
||||
|
||||
expect(project.targets).toMatchObject({
|
||||
build: {
|
||||
executor: '@nrwl/rollup:rollup',
|
||||
outputs: ['{options.outputPath}'],
|
||||
defaultConfiguration: 'production',
|
||||
options: {
|
||||
main: 'libs/mypkg/src/main.ts',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(readJson(tree, 'libs/mypkg/package.json')).toEqual({
|
||||
name: '@proj/mypkg',
|
||||
version: '0.0.1',
|
||||
});
|
||||
});
|
||||
|
||||
it('should respect existing package.json file', async () => {
|
||||
writeJson(tree, 'libs/mypkg/package.json', {
|
||||
name: '@acme/mypkg',
|
||||
version: '1.0.0',
|
||||
});
|
||||
await rollupProjectGenerator(tree, {
|
||||
project: 'mypkg',
|
||||
});
|
||||
|
||||
expect(readJson(tree, 'libs/mypkg/package.json')).toEqual({
|
||||
name: '@acme/mypkg',
|
||||
version: '1.0.0',
|
||||
});
|
||||
});
|
||||
|
||||
it('should support --main option', async () => {
|
||||
await rollupProjectGenerator(tree, {
|
||||
project: 'mypkg',
|
||||
main: 'libs/mypkg/index.ts',
|
||||
});
|
||||
|
||||
const project = readProjectConfiguration(tree, 'mypkg');
|
||||
|
||||
expect(project.targets).toMatchObject({
|
||||
build: {
|
||||
executor: '@nrwl/rollup:rollup',
|
||||
outputs: ['{options.outputPath}'],
|
||||
defaultConfiguration: 'production',
|
||||
options: {
|
||||
main: 'libs/mypkg/index.ts',
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should support --tsConfig option', async () => {
|
||||
await rollupProjectGenerator(tree, {
|
||||
project: 'mypkg',
|
||||
tsConfig: 'libs/mypkg/tsconfig.custom.json',
|
||||
});
|
||||
|
||||
const project = readProjectConfiguration(tree, 'mypkg');
|
||||
|
||||
expect(project.targets).toMatchObject({
|
||||
build: {
|
||||
executor: '@nrwl/rollup:rollup',
|
||||
outputs: ['{options.outputPath}'],
|
||||
defaultConfiguration: 'production',
|
||||
options: {
|
||||
tsConfig: 'libs/mypkg/tsconfig.custom.json',
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
105
packages/rollup/src/generators/rollup-project/rollup-project.ts
Normal file
105
packages/rollup/src/generators/rollup-project/rollup-project.ts
Normal file
@ -0,0 +1,105 @@
|
||||
import type { Tree } from '@nrwl/devkit';
|
||||
import {
|
||||
convertNxGenerator,
|
||||
formatFiles,
|
||||
getImportPath,
|
||||
getWorkspaceLayout,
|
||||
joinPathFragments,
|
||||
readProjectConfiguration,
|
||||
updateProjectConfiguration,
|
||||
writeJson,
|
||||
} from '@nrwl/devkit';
|
||||
|
||||
import { rollupInitGenerator } from '../init/init';
|
||||
import { RollupExecutorOptions } from '../../executors/rollup/schema';
|
||||
import { RollupProjectSchema } from './schema';
|
||||
|
||||
export async function rollupProjectGenerator(
|
||||
tree: Tree,
|
||||
options: RollupProjectSchema
|
||||
) {
|
||||
const task = await rollupInitGenerator(tree, options);
|
||||
checkForTargetConflicts(tree, options);
|
||||
addBuildTarget(tree, options);
|
||||
await formatFiles(tree);
|
||||
return task;
|
||||
}
|
||||
|
||||
function checkForTargetConflicts(tree: Tree, options: RollupProjectSchema) {
|
||||
const project = readProjectConfiguration(tree, options.project);
|
||||
if (project.targets.build) {
|
||||
throw new Error(`Project "${project.name}" already has a build target.`);
|
||||
}
|
||||
|
||||
if (options.devServer && project.targets.serve) {
|
||||
throw new Error(`Project "${project.name}" already has a serve target.`);
|
||||
}
|
||||
}
|
||||
|
||||
function addBuildTarget(tree: Tree, options: RollupProjectSchema) {
|
||||
const project = readProjectConfiguration(tree, options.project);
|
||||
const packageJsonPath = joinPathFragments(project.root, 'package.json');
|
||||
|
||||
if (!tree.exists(packageJsonPath)) {
|
||||
const { npmScope } = getWorkspaceLayout(tree);
|
||||
const importPath =
|
||||
options.importPath || getImportPath(npmScope, options.project);
|
||||
writeJson(tree, packageJsonPath, {
|
||||
name: importPath,
|
||||
version: '0.0.1',
|
||||
});
|
||||
}
|
||||
const tsConfig =
|
||||
options.tsConfig ?? joinPathFragments(project.root, 'tsconfig.lib.json');
|
||||
|
||||
const buildOptions: RollupExecutorOptions = {
|
||||
main: options.main ?? joinPathFragments(project.root, 'src/main.ts'),
|
||||
outputPath: joinPathFragments('dist', project.root),
|
||||
compiler: options.compiler ?? 'babel',
|
||||
tsConfig,
|
||||
project: `${project.root}/package.json`,
|
||||
external: options.external,
|
||||
};
|
||||
|
||||
if (options.rollupConfig) {
|
||||
buildOptions.rollupConfig = options.rollupConfig;
|
||||
}
|
||||
|
||||
if (tree.exists(joinPathFragments(project.root, 'README.md'))) {
|
||||
buildOptions.assets = [
|
||||
{
|
||||
glob: `${project.root}/README.md`,
|
||||
input: '.',
|
||||
output: '.',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
updateProjectConfiguration(tree, options.project, {
|
||||
...project,
|
||||
targets: {
|
||||
...project.targets,
|
||||
build: {
|
||||
executor: '@nrwl/rollup:rollup',
|
||||
outputs: ['{options.outputPath}'],
|
||||
defaultConfiguration: 'production',
|
||||
options: buildOptions,
|
||||
configurations: {
|
||||
production: {
|
||||
optimization: true,
|
||||
sourceMap: false,
|
||||
namedChunks: false,
|
||||
extractLicenses: true,
|
||||
vendorChunk: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export default rollupProjectGenerator;
|
||||
|
||||
export const rollupProjectSchematic = convertNxGenerator(
|
||||
rollupProjectGenerator
|
||||
);
|
||||
12
packages/rollup/src/generators/rollup-project/schema.d.ts
vendored
Normal file
12
packages/rollup/src/generators/rollup-project/schema.d.ts
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
export interface RollupProjectSchema {
|
||||
project: string;
|
||||
main?: string;
|
||||
tsConfig?: string;
|
||||
compiler?: 'babel' | 'swc' | 'tsc';
|
||||
devServer?: boolean;
|
||||
skipFormat?: boolean;
|
||||
skipPackageJson?: boolean;
|
||||
importPath?: string;
|
||||
external?: string[];
|
||||
rollupConfig?: string;
|
||||
}
|
||||
61
packages/rollup/src/generators/rollup-project/schema.json
Normal file
61
packages/rollup/src/generators/rollup-project/schema.json
Normal file
@ -0,0 +1,61 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/schema",
|
||||
"$id": "NxRollupProject",
|
||||
"cli": "nx",
|
||||
"title": "Add Rollup Configuration to a project",
|
||||
"description": "Add Rollup Configuration to a project.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"project": {
|
||||
"type": "string",
|
||||
"description": "The name of the project.",
|
||||
"$default": {
|
||||
"$source": "argv",
|
||||
"index": 0
|
||||
},
|
||||
"x-dropdown": "project",
|
||||
"x-prompt": "What is the name of the project to set up a rollup for?"
|
||||
},
|
||||
"compiler": {
|
||||
"type": "string",
|
||||
"enum": ["babel", "swc", "tsc"],
|
||||
"description": "The compiler to use to build source.",
|
||||
"default": "babel"
|
||||
},
|
||||
"main": {
|
||||
"type": "string",
|
||||
"description": "Path relative to the workspace root for the main entry file. Defaults to '<projectRoot>/src/main.ts'.",
|
||||
"alias": "entryFile"
|
||||
},
|
||||
"tsConfig": {
|
||||
"type": "string",
|
||||
"description": "Path relative to the workspace root for the tsconfig file to build with. Defaults to '<projectRoot>/tsconfig.app.json'."
|
||||
},
|
||||
"skipFormat": {
|
||||
"description": "Skip formatting files.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"skipPackageJson": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Do not add dependencies to `package.json`."
|
||||
},
|
||||
"importPath": {
|
||||
"type": "string",
|
||||
"description": "The library name used to import it, like `@myorg/my-awesome-lib`."
|
||||
},
|
||||
"external": {
|
||||
"type": "array",
|
||||
"description": "A list of external modules that will not be bundled (`react`, `react-dom`, etc.).",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"rollupConfig": {
|
||||
"type": "string",
|
||||
"description": "Path relative to workspace root to a custom rollup file that takes a config object and returns an updated config."
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
14
packages/rollup/src/utils/fs.ts
Normal file
14
packages/rollup/src/utils/fs.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import * as path from 'path';
|
||||
import { removeSync } from 'fs-extra';
|
||||
|
||||
/**
|
||||
* Delete an output directory, but error out if it's the root of the project.
|
||||
*/
|
||||
export function deleteOutputDir(root: string, outputPath: string) {
|
||||
const resolvedOutputPath = path.resolve(root, outputPath);
|
||||
if (resolvedOutputPath === root) {
|
||||
throw new Error('Output path MUST not be project root directory!');
|
||||
}
|
||||
|
||||
removeSync(resolvedOutputPath);
|
||||
}
|
||||
3
packages/rollup/src/utils/versions.ts
Normal file
3
packages/rollup/src/utils/versions.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export const nxVersion = require('../../package.json').version;
|
||||
export const swcLoaderVersion = '0.1.15';
|
||||
export const tsLibVersion = '^2.3.0';
|
||||
16
packages/rollup/tsconfig.json
Normal file
16
packages/rollup/tsconfig.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"module": "commonjs"
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
10
packages/rollup/tsconfig.lib.json
Normal file
10
packages/rollup/tsconfig.lib.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"declaration": true,
|
||||
"types": []
|
||||
},
|
||||
"include": ["**/*.ts"],
|
||||
"exclude": ["jest.config.ts", "**/*.spec.ts", "**/*.test.ts"]
|
||||
}
|
||||
9
packages/rollup/tsconfig.spec.json
Normal file
9
packages/rollup/tsconfig.spec.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"module": "commonjs",
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
"include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"]
|
||||
}
|
||||
@ -41,30 +41,16 @@
|
||||
"@nrwl/jest": "file:../jest",
|
||||
"@nrwl/js": "file:../js",
|
||||
"@nrwl/linter": "file:../linter",
|
||||
"@nrwl/rollup": "file:../rollup",
|
||||
"@nrwl/webpack": "file:../webpack",
|
||||
"@nrwl/workspace": "file:../workspace",
|
||||
"@rollup/plugin-babel": "^5.3.0",
|
||||
"@rollup/plugin-commonjs": "^20.0.0",
|
||||
"@rollup/plugin-image": "^2.1.0",
|
||||
"@rollup/plugin-json": "^4.1.0",
|
||||
"@rollup/plugin-node-resolve": "^13.0.4",
|
||||
"autoprefixer": "^10.4.9",
|
||||
"babel-plugin-const-enum": "^1.0.1",
|
||||
"babel-plugin-macros": "^2.8.0",
|
||||
"babel-plugin-transform-async-to-promises": "^0.8.15",
|
||||
"babel-plugin-transform-typescript-metadata": "^0.3.1",
|
||||
"chalk": "4.1.0",
|
||||
"chokidar": "^3.5.1",
|
||||
"fs-extra": "^10.1.0",
|
||||
"http-server": "14.1.0",
|
||||
"ignore": "^5.0.4",
|
||||
"postcss": "^8.4.14",
|
||||
"rollup": "^2.56.2",
|
||||
"rollup-plugin-copy": "^3.4.0",
|
||||
"rollup-plugin-peer-deps-external": "^2.2.4",
|
||||
"rollup-plugin-postcss": "^4.0.1",
|
||||
"rollup-plugin-typescript2": "^0.31.1",
|
||||
"rxjs": "^6.5.4",
|
||||
"tslib": "^2.3.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,46 +0,0 @@
|
||||
import { dirname } from 'path';
|
||||
|
||||
import { AssetGlobPattern } from '@nrwl/webpack';
|
||||
import { normalizeAssets, normalizePluginPath } from '@nrwl/webpack';
|
||||
import { WebRollupOptions } from '../schema';
|
||||
|
||||
export interface NormalizedWebRollupOptions extends WebRollupOptions {
|
||||
entryRoot: string;
|
||||
projectRoot: string;
|
||||
assets: AssetGlobPattern[];
|
||||
rollupConfig: string[];
|
||||
}
|
||||
|
||||
export function normalizeWebRollupOptions(
|
||||
options: WebRollupOptions,
|
||||
root: string,
|
||||
sourceRoot: string
|
||||
): NormalizedWebRollupOptions {
|
||||
const entryFile = `${root}/${options.entryFile}`;
|
||||
const entryRoot = dirname(entryFile);
|
||||
const project = `${root}/${options.project}`;
|
||||
const projectRoot = dirname(project);
|
||||
const outputPath = `${root}/${options.outputPath}`;
|
||||
|
||||
if (options.buildableProjectDepsInPackageJsonType == undefined) {
|
||||
options.buildableProjectDepsInPackageJsonType = 'peerDependencies';
|
||||
}
|
||||
|
||||
return {
|
||||
...options,
|
||||
// de-dupe formats
|
||||
format: Array.from(new Set(options.format)),
|
||||
rollupConfig: []
|
||||
.concat(options.rollupConfig)
|
||||
.filter(Boolean)
|
||||
.map((p) => normalizePluginPath(p, root)),
|
||||
assets: options.assets
|
||||
? normalizeAssets(options.assets, root, sourceRoot)
|
||||
: undefined,
|
||||
entryFile,
|
||||
entryRoot,
|
||||
project,
|
||||
projectRoot,
|
||||
outputPath,
|
||||
};
|
||||
}
|
||||
@ -1,327 +1,21 @@
|
||||
import * as rollup from 'rollup';
|
||||
import * as peerDepsExternal from 'rollup-plugin-peer-deps-external';
|
||||
import { getBabelInputPlugin } from '@rollup/plugin-babel';
|
||||
import { join } from 'path';
|
||||
import { from, Observable, of } from 'rxjs';
|
||||
import { catchError, concatMap, last, scan, tap } from 'rxjs/operators';
|
||||
import { eachValueFrom } from '@nrwl/devkit/src/utils/rxjs-for-await';
|
||||
import * as autoprefixer from 'autoprefixer';
|
||||
import type { ExecutorContext } from '@nrwl/devkit';
|
||||
import { logger, names, readJsonFile } from '@nrwl/devkit';
|
||||
/**
|
||||
* This is here for backwards-compat.
|
||||
* TODO(jack): remove in Nx 16.
|
||||
*/
|
||||
import {
|
||||
calculateProjectDependencies,
|
||||
computeCompilerOptionsPaths,
|
||||
DependentBuildableProjectNode,
|
||||
} from '@nrwl/workspace/src/utilities/buildable-libs-utils';
|
||||
import resolve from '@rollup/plugin-node-resolve';
|
||||
rollupExecutor as _rollupExecutor,
|
||||
RollupExecutorOptions as WebRollupOptions,
|
||||
} from '@nrwl/rollup';
|
||||
|
||||
import { AssetGlobPattern } from '@nrwl/webpack';
|
||||
import { WebRollupOptions } from './schema';
|
||||
import { runRollup } from './lib/run-rollup';
|
||||
import {
|
||||
NormalizedWebRollupOptions,
|
||||
normalizeWebRollupOptions,
|
||||
} from './lib/normalize';
|
||||
import { analyze } from './lib/analyze-plugin';
|
||||
import { deleteOutputDir } from '../../utils/fs';
|
||||
import { swc } from './lib/swc-plugin';
|
||||
import { validateTypes } from './lib/validate-types';
|
||||
import { updatePackageJson } from './lib/update-package-json';
|
||||
export { WebRollupOptions };
|
||||
|
||||
// These use require because the ES import isn't correct.
|
||||
const commonjs = require('@rollup/plugin-commonjs');
|
||||
const image = require('@rollup/plugin-image');
|
||||
|
||||
const json = require('@rollup/plugin-json');
|
||||
const copy = require('rollup-plugin-copy');
|
||||
const postcss = require('rollup-plugin-postcss');
|
||||
|
||||
const fileExtensions = ['.js', '.jsx', '.ts', '.tsx'];
|
||||
export default async function* rollupExecutor(
|
||||
rawOptions: WebRollupOptions,
|
||||
context: ExecutorContext
|
||||
) {
|
||||
process.env.NODE_ENV ??= 'production';
|
||||
|
||||
const project = context.workspace.projects[context.projectName];
|
||||
const sourceRoot = project.sourceRoot;
|
||||
const { target, dependencies } = calculateProjectDependencies(
|
||||
context.projectGraph,
|
||||
context.root,
|
||||
context.projectName,
|
||||
context.targetName,
|
||||
context.configurationName,
|
||||
true
|
||||
);
|
||||
|
||||
const options = normalizeWebRollupOptions(
|
||||
rawOptions,
|
||||
context.root,
|
||||
sourceRoot
|
||||
);
|
||||
|
||||
// TODO(jack): Remove UMD in Nx 15
|
||||
if (options.format.includes('umd')) {
|
||||
if (options.format.includes('cjs')) {
|
||||
throw new Error(
|
||||
'Cannot use both UMD and CJS. We recommend you use ESM or CJS.'
|
||||
);
|
||||
} else {
|
||||
logger.warn('UMD format is deprecated and will be removed in Nx 15');
|
||||
}
|
||||
}
|
||||
const packageJson = readJsonFile(options.project);
|
||||
|
||||
const npmDeps = (context.projectGraph.dependencies[context.projectName] ?? [])
|
||||
.filter((d) => d.target.startsWith('npm:'))
|
||||
.map((d) => d.target.slice(4));
|
||||
|
||||
const rollupOptions = createRollupOptions(
|
||||
options,
|
||||
dependencies,
|
||||
context,
|
||||
packageJson,
|
||||
sourceRoot,
|
||||
npmDeps
|
||||
);
|
||||
|
||||
if (options.compiler === 'swc') {
|
||||
try {
|
||||
await validateTypes({
|
||||
workspaceRoot: context.root,
|
||||
projectRoot: options.projectRoot,
|
||||
tsconfig: options.tsConfig,
|
||||
});
|
||||
} catch {
|
||||
return { success: false };
|
||||
}
|
||||
}
|
||||
|
||||
if (options.watch) {
|
||||
const watcher = rollup.watch(rollupOptions);
|
||||
return yield* eachValueFrom(
|
||||
new Observable<{ success: boolean }>((obs) => {
|
||||
watcher.on('event', (data) => {
|
||||
if (data.code === 'START') {
|
||||
logger.info(`Bundling ${context.projectName}...`);
|
||||
} else if (data.code === 'END') {
|
||||
updatePackageJson(
|
||||
options,
|
||||
context,
|
||||
target,
|
||||
dependencies,
|
||||
packageJson
|
||||
);
|
||||
logger.info('Bundle complete. Watching for file changes...');
|
||||
obs.next({ success: true });
|
||||
} else if (data.code === 'ERROR') {
|
||||
logger.error(`Error during bundle: ${data.error.message}`);
|
||||
obs.next({ success: false });
|
||||
}
|
||||
});
|
||||
// Teardown logic. Close watcher when unsubscribed.
|
||||
return () => watcher.close();
|
||||
})
|
||||
);
|
||||
} else {
|
||||
logger.info(`Bundling ${context.projectName}...`);
|
||||
|
||||
// Delete output path before bundling
|
||||
if (options.deleteOutputPath) {
|
||||
deleteOutputDir(context.root, options.outputPath);
|
||||
}
|
||||
|
||||
const start = process.hrtime.bigint();
|
||||
|
||||
return from(rollupOptions)
|
||||
.pipe(
|
||||
concatMap((opts) =>
|
||||
runRollup(opts).pipe(
|
||||
catchError((e) => {
|
||||
logger.error(`Error during bundle: ${e}`);
|
||||
return of({ success: false });
|
||||
})
|
||||
)
|
||||
),
|
||||
scan(
|
||||
(acc, result) => {
|
||||
if (!acc.success) return acc;
|
||||
return result;
|
||||
export async function* rollupExecutor(options: any, context: any) {
|
||||
return yield* _rollupExecutor(
|
||||
{
|
||||
...options,
|
||||
main: options.main || options.entryFile,
|
||||
},
|
||||
{ success: true }
|
||||
),
|
||||
last(),
|
||||
tap({
|
||||
next: (result) => {
|
||||
if (result.success) {
|
||||
const end = process.hrtime.bigint();
|
||||
const duration = `${(Number(end - start) / 1_000_000_000).toFixed(
|
||||
2
|
||||
)}s`;
|
||||
|
||||
updatePackageJson(
|
||||
options,
|
||||
context,
|
||||
target,
|
||||
dependencies,
|
||||
packageJson
|
||||
context
|
||||
);
|
||||
logger.info(`⚡ Done in ${duration}`);
|
||||
} else {
|
||||
logger.error(`Bundle failed: ${context.projectName}`);
|
||||
}
|
||||
},
|
||||
})
|
||||
)
|
||||
.toPromise();
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
export function createRollupOptions(
|
||||
options: NormalizedWebRollupOptions,
|
||||
dependencies: DependentBuildableProjectNode[],
|
||||
context: ExecutorContext,
|
||||
packageJson: any,
|
||||
sourceRoot: string,
|
||||
npmDeps: string[]
|
||||
): rollup.InputOptions[] {
|
||||
const useBabel = options.compiler === 'babel';
|
||||
const useSwc = options.compiler === 'swc';
|
||||
|
||||
return options.format.map((format, idx) => {
|
||||
const plugins = [
|
||||
copy({
|
||||
targets: convertCopyAssetsToRollupOptions(
|
||||
options.outputPath,
|
||||
options.assets
|
||||
),
|
||||
}),
|
||||
image(),
|
||||
json(),
|
||||
useBabel &&
|
||||
require('rollup-plugin-typescript2')({
|
||||
check: true,
|
||||
tsconfig: options.tsConfig,
|
||||
tsconfigOverride: {
|
||||
compilerOptions: createCompilerOptions(options, dependencies),
|
||||
},
|
||||
}),
|
||||
peerDepsExternal({
|
||||
packageJsonPath: options.project,
|
||||
}),
|
||||
postcss({
|
||||
inject: true,
|
||||
extract: options.extractCss,
|
||||
autoModules: true,
|
||||
plugins: [autoprefixer],
|
||||
use: {
|
||||
less: {
|
||||
javascriptEnabled: options.javascriptEnabled,
|
||||
},
|
||||
},
|
||||
}),
|
||||
resolve({
|
||||
preferBuiltins: true,
|
||||
extensions: fileExtensions,
|
||||
}),
|
||||
useSwc && swc(),
|
||||
useBabel &&
|
||||
getBabelInputPlugin({
|
||||
// Let's `@nrwl/web/babel` preset know that we are packaging.
|
||||
caller: {
|
||||
// @ts-ignore
|
||||
// Ignoring type checks for caller since we have custom attributes
|
||||
isNxPackage: true,
|
||||
// Always target esnext and let rollup handle cjs/umd
|
||||
supportsStaticESM: true,
|
||||
isModern: true,
|
||||
},
|
||||
cwd: join(context.root, sourceRoot),
|
||||
rootMode: 'upward',
|
||||
babelrc: true,
|
||||
extensions: fileExtensions,
|
||||
babelHelpers: 'bundled',
|
||||
skipPreflightCheck: true, // pre-flight check may yield false positives and also slows down the build
|
||||
exclude: /node_modules/,
|
||||
plugins: [
|
||||
format === 'esm'
|
||||
? undefined
|
||||
: require.resolve('babel-plugin-transform-async-to-promises'),
|
||||
].filter(Boolean),
|
||||
}),
|
||||
commonjs(),
|
||||
analyze(),
|
||||
];
|
||||
|
||||
const globals = options.globals
|
||||
? options.globals.reduce(
|
||||
(acc, item) => {
|
||||
acc[item.moduleId] = item.global;
|
||||
return acc;
|
||||
},
|
||||
{ 'react/jsx-runtime': 'jsxRuntime' }
|
||||
)
|
||||
: { 'react/jsx-runtime': 'jsxRuntime' };
|
||||
|
||||
const externalPackages = dependencies
|
||||
.map((d) => d.name)
|
||||
.concat(options.external || [])
|
||||
.concat(Object.keys(packageJson.dependencies || {}));
|
||||
|
||||
const rollupConfig = {
|
||||
input: options.entryFile,
|
||||
output: {
|
||||
globals,
|
||||
format,
|
||||
dir: `${options.outputPath}`,
|
||||
name: options.umdName || names(context.projectName).className,
|
||||
entryFileNames: `[name].${format === 'esm' ? 'js' : 'cjs'}`,
|
||||
chunkFileNames: `[name].${format === 'esm' ? 'js' : 'cjs'}`,
|
||||
// umd doesn't support code-split bundles
|
||||
inlineDynamicImports: format === 'umd',
|
||||
},
|
||||
external: (id) =>
|
||||
externalPackages.some(
|
||||
(name) => id === name || id.startsWith(`${name}/`)
|
||||
) || npmDeps.some((name) => id === name || id.startsWith(`${name}/`)), // Could be a deep import
|
||||
plugins,
|
||||
};
|
||||
|
||||
return options.rollupConfig.reduce((currentConfig, plugin) => {
|
||||
return require(plugin)(currentConfig, options);
|
||||
}, rollupConfig);
|
||||
});
|
||||
}
|
||||
|
||||
function createCompilerOptions(options, dependencies) {
|
||||
const compilerOptionPaths = computeCompilerOptionsPaths(
|
||||
options.tsConfig,
|
||||
dependencies
|
||||
);
|
||||
|
||||
return {
|
||||
rootDir: options.entryRoot,
|
||||
allowJs: false,
|
||||
declaration: true,
|
||||
paths: compilerOptionPaths,
|
||||
};
|
||||
}
|
||||
|
||||
interface RollupCopyAssetOption {
|
||||
src: string;
|
||||
dest: string;
|
||||
}
|
||||
|
||||
function convertCopyAssetsToRollupOptions(
|
||||
outputPath: string,
|
||||
assets: AssetGlobPattern[]
|
||||
): RollupCopyAssetOption[] {
|
||||
return assets
|
||||
? assets.map((a) => ({
|
||||
src: join(a.input, a.glob).replace(/\\/g, '/'),
|
||||
dest: join(outputPath, a.output).replace(/\\/g, '/'),
|
||||
}))
|
||||
: undefined;
|
||||
}
|
||||
export default rollupExecutor;
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
import { dirname, join, relative, resolve } from 'path';
|
||||
import { dirname, join, relative } from 'path';
|
||||
import { directoryExists, fileExists } from './fileutils';
|
||||
import type { ProjectGraph, ProjectGraphProjectNode } from '@nrwl/devkit';
|
||||
import {
|
||||
getOutputsForTargetAndConfiguration,
|
||||
ProjectGraphExternalNode,
|
||||
readJsonFile,
|
||||
stripIndents,
|
||||
writeJsonFile,
|
||||
getOutputsForTargetAndConfiguration,
|
||||
} from '@nrwl/devkit';
|
||||
import * as ts from 'typescript';
|
||||
import { unlinkSync } from 'fs';
|
||||
@ -163,8 +163,14 @@ function readTsConfigWithRemappedPaths(
|
||||
return generatedTsConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Util function to create tsconfig compilerOptions object with support for workspace libs paths.
|
||||
*
|
||||
* @param tsConfig String of config path or object parsed via ts.parseJsonConfigFileContent.
|
||||
* @param dependencies Dependencies calculated by Nx.
|
||||
*/
|
||||
export function computeCompilerOptionsPaths(
|
||||
tsConfig: string,
|
||||
tsConfig: string | ts.ParsedCommandLine,
|
||||
dependencies: DependentBuildableProjectNode[]
|
||||
) {
|
||||
const paths = readPaths(tsConfig) || {};
|
||||
@ -172,16 +178,21 @@ export function computeCompilerOptionsPaths(
|
||||
return paths;
|
||||
}
|
||||
|
||||
function readPaths(tsConfig: string) {
|
||||
function readPaths(tsConfig: string | ts.ParsedCommandLine) {
|
||||
try {
|
||||
const parsedTSConfig = ts.readConfigFile(tsConfig, ts.sys.readFile).config;
|
||||
if (
|
||||
parsedTSConfig.compilerOptions &&
|
||||
parsedTSConfig.compilerOptions.paths
|
||||
) {
|
||||
return parsedTSConfig.compilerOptions.paths;
|
||||
} else if (parsedTSConfig.extends) {
|
||||
return readPaths(resolve(dirname(tsConfig), parsedTSConfig.extends));
|
||||
let config: ts.ParsedCommandLine;
|
||||
if (typeof tsConfig === 'string') {
|
||||
const configFile = ts.readConfigFile(tsConfig, ts.sys.readFile);
|
||||
config = ts.parseJsonConfigFileContent(
|
||||
configFile.config,
|
||||
ts.sys,
|
||||
dirname(tsConfig)
|
||||
);
|
||||
} else {
|
||||
config = tsConfig;
|
||||
}
|
||||
if (config.options?.paths) {
|
||||
return config.options.paths;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -86,6 +86,7 @@ const IGNORE_MATCHES = {
|
||||
'swc-loader',
|
||||
'tsconfig-paths-webpack-plugin',
|
||||
],
|
||||
rollup: ['@swc/core'],
|
||||
storybook: [
|
||||
'@angular-devkit/architect',
|
||||
'@angular-devkit/core',
|
||||
|
||||
@ -19,6 +19,7 @@ const IGNORE_MATCHES = {
|
||||
node: [],
|
||||
'nx-plugin': [],
|
||||
react: [],
|
||||
rollup: [],
|
||||
storybook: [],
|
||||
nx: ['glob'],
|
||||
web: ['http-server'],
|
||||
|
||||
@ -83,6 +83,8 @@
|
||||
"@nrwl/react": ["packages/react"],
|
||||
"@nrwl/react-native": ["packages/react-native"],
|
||||
"@nrwl/react/*": ["packages/react/*"],
|
||||
"@nrwl/rollup": ["packages/rollup"],
|
||||
"@nrwl/rollup/*": ["packages/rollup/*"],
|
||||
"@nrwl/storybook": ["packages/storybook"],
|
||||
"@nrwl/storybook/*": ["packages/storybook/*"],
|
||||
"@nrwl/tao": ["packages/tao"],
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
"e2e-nx-run": "e2e/nx-run",
|
||||
"e2e-react": "e2e/react",
|
||||
"e2e-react-native": "e2e/react-native",
|
||||
"e2e-rollup": "e2e/rollup",
|
||||
"e2e-storybook": "e2e/storybook",
|
||||
"e2e-storybook-angular": "e2e/storybook-angular",
|
||||
"e2e-utils": "e2e/utils",
|
||||
@ -71,6 +72,7 @@
|
||||
"nx-plugin": "packages/nx-plugin",
|
||||
"react": "packages/react",
|
||||
"react-native": "packages/react-native",
|
||||
"rollup": "packages/rollup",
|
||||
"storybook": "packages/storybook",
|
||||
"tao": "packages/tao",
|
||||
"typedoc-theme": "typedoc-theme",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user