-
Notifications
You must be signed in to change notification settings - Fork 205
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
af94e15
commit 53a9aa7
Showing
5 changed files
with
240 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,22 @@ | ||
{ | ||
"$schema": "../../node_modules/@angular-devkit/schematics/collection-schema.json", | ||
"name": "module-federation", | ||
"name": "native-federation", | ||
"version": "0.0.1", | ||
"schematics": { | ||
"ng-add": { | ||
"factory": "./src/schematics/init/schematic", | ||
"schema": "./src/schematics/init/schema.json", | ||
"description": "Initialize an angular project for webpack module federation" | ||
"description": "Initialize an angular project for native federation" | ||
}, | ||
"init": { | ||
"factory": "./src/schematics/init/schematic", | ||
"schema": "./src/schematics/init/schema.json", | ||
"description": "Initialize an angular project for webpack module federation" | ||
"description": "Initialize an angular project for native federation" | ||
}, | ||
"remove": { | ||
"factory": "./src/schematics/remove/schematic", | ||
"schema": "./src/schematics/remove/schema.json", | ||
"description": "Removes native federation" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export interface MfSchematicSchema { | ||
project: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"$schema": "http://json-schema.org/schema", | ||
"$id": "mf", | ||
"title": "", | ||
"type": "object", | ||
"properties": { | ||
"project": { | ||
"type": "string", | ||
"description": "The project to add module federation", | ||
"$default": { | ||
"$source": "argv", | ||
"index": 0 | ||
}, | ||
"x-prompt": "Project name (press enter for default project)" | ||
} | ||
} | ||
} |
179 changes: 179 additions & 0 deletions
179
libs/native-federation/src/schematics/remove/schematic.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
import { Rule, Tree, noop } from '@angular-devkit/schematics'; | ||
|
||
import { MfSchematicSchema } from './schema'; | ||
|
||
import * as path from 'path'; | ||
|
||
type NormalizedOptions = { | ||
polyfills: string; | ||
projectName: string; | ||
projectRoot: string; | ||
projectSourceRoot: string; | ||
manifestPath: string; | ||
projectConfig: any; | ||
main: string; | ||
}; | ||
|
||
export default function remove(options: MfSchematicSchema): Rule { | ||
return async function (tree /*, context*/) { | ||
const workspaceFileName = getWorkspaceFileName(tree); | ||
const workspace = JSON.parse(tree.read(workspaceFileName).toString('utf8')); | ||
|
||
const normalized = normalizeOptions(options, workspace); | ||
|
||
const { polyfills, projectRoot } = normalized; | ||
|
||
const bootstrapPath = path.join(projectRoot, 'src/bootstrap.ts'); | ||
const mainPath = path.join(projectRoot, 'src/main.ts'); | ||
|
||
makeMainSync(tree, bootstrapPath, mainPath); | ||
updatePolyfills(tree, polyfills); | ||
updateWorkspaceConfig(tree, normalized, workspace, workspaceFileName); | ||
}; | ||
} | ||
|
||
function makeMainSync(tree, bootstrapPath: string, mainPath: string) { | ||
if (tree.exists(bootstrapPath) && tree.exists(mainPath)) { | ||
tree.delete(mainPath); | ||
tree.rename(bootstrapPath, mainPath); | ||
} | ||
} | ||
|
||
function updateWorkspaceConfig( | ||
tree: Tree, | ||
options: NormalizedOptions, | ||
workspace: any, | ||
workspaceFileName: string | ||
) { | ||
const { projectConfig } = options; | ||
|
||
if (!projectConfig?.architect?.build || !projectConfig?.architect?.serve) { | ||
throw new Error( | ||
`The project doen't have a build or serve target in angular.json!` | ||
); | ||
} | ||
|
||
if (projectConfig.architect.esbuild) { | ||
projectConfig.architect.build = projectConfig.architect.esbuild; | ||
delete projectConfig.architect.esbuild; | ||
} | ||
|
||
if (projectConfig.architect['serve-original']) { | ||
projectConfig.architect.serve = projectConfig.architect['serve-original']; | ||
delete projectConfig.architect['serve-original']; | ||
} | ||
|
||
if (projectConfig.architect.serve) { | ||
const conf = projectConfig.architect.serve.configurations; | ||
conf.production.browserTarget = conf.production.browserTarget.replace( | ||
':esbuild:', | ||
':build:' | ||
); | ||
conf.development.browserTarget = conf.development.browserTarget.replace( | ||
':esbuild:', | ||
':build:' | ||
); | ||
} | ||
|
||
tree.overwrite(workspaceFileName, JSON.stringify(workspace, null, '\t')); | ||
} | ||
|
||
function normalizeOptions( | ||
options: MfSchematicSchema, | ||
workspace: any | ||
): NormalizedOptions { | ||
if (!options.project) { | ||
options.project = workspace.defaultProject; | ||
} | ||
|
||
const projects = Object.keys(workspace.projects); | ||
|
||
if (!options.project && projects.length === 0) { | ||
throw new Error( | ||
`No default project found. Please specifiy a project name!` | ||
); | ||
} | ||
|
||
if (!options.project) { | ||
console.log( | ||
'Using first configured project as default project: ' + projects[0] | ||
); | ||
options.project = projects[0]; | ||
} | ||
|
||
const projectName = options.project; | ||
const projectConfig = workspace.projects[projectName]; | ||
|
||
if (!projectConfig) { | ||
throw new Error(`Project ${projectName} not found!`); | ||
} | ||
|
||
const projectRoot: string = projectConfig.root?.replace(/\\/g, '/'); | ||
const projectSourceRoot: string = projectConfig.sourceRoot?.replace( | ||
/\\/g, | ||
'/' | ||
); | ||
|
||
const manifestPath = path | ||
.join(projectRoot, 'src/assets/federation.manifest.json') | ||
.replace(/\\/g, '/'); | ||
|
||
const main = projectConfig.architect.build.options.main; | ||
|
||
if (!projectConfig.architect.build.options.polyfills) { | ||
projectConfig.architect.build.options.polyfills = []; | ||
} | ||
|
||
const polyfills = projectConfig.architect.build.options.polyfills; | ||
return { | ||
polyfills, | ||
projectName, | ||
projectRoot, | ||
projectSourceRoot, | ||
manifestPath, | ||
projectConfig, | ||
main, | ||
}; | ||
} | ||
|
||
function updatePolyfills(tree, polyfills: any) { | ||
if (typeof polyfills === 'string') { | ||
updatePolyfillsFile(tree, polyfills); | ||
} else { | ||
updatePolyfillsArray(tree, polyfills); | ||
} | ||
} | ||
|
||
function updatePolyfillsFile(tree, polyfills: any) { | ||
let polyfillsContent = tree.readText(polyfills); | ||
if (polyfillsContent.includes('es-module-shims')) { | ||
polyfillsContent = polyfillsContent.replace( | ||
`import 'es-module-shims';`, | ||
'' | ||
); | ||
tree.overwrite(polyfills, polyfillsContent); | ||
} | ||
} | ||
|
||
function updatePolyfillsArray(tree, polyfills: any) { | ||
const polyfillsConfig = polyfills as string[]; | ||
|
||
const index = polyfillsConfig.findIndex((p) => p === 'es-module-shims'); | ||
if (index === -1) { | ||
return; | ||
} | ||
|
||
polyfillsConfig.splice(index, 1); | ||
} | ||
|
||
export function getWorkspaceFileName(tree: Tree): string { | ||
if (tree.exists('angular.json')) { | ||
return 'angular.json'; | ||
} | ||
if (tree.exists('workspace.json')) { | ||
return 'workspace.json'; | ||
} | ||
throw new Error( | ||
"angular.json or workspace.json expected! Did you call this in your project's root?" | ||
); | ||
} |