index.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. "use strict";
  2. /**
  3. * @license
  4. * Copyright Google LLC All Rights Reserved.
  5. *
  6. * Use of this source code is governed by an MIT-style license that can be
  7. * found in the LICENSE file at https://angular.dev/license
  8. */
  9. Object.defineProperty(exports, "__esModule", { value: true });
  10. exports.default = default_1;
  11. const core_1 = require("@angular-devkit/core");
  12. const schematics_1 = require("@angular-devkit/schematics");
  13. const parse_name_1 = require("../utility/parse-name");
  14. const paths_1 = require("../utility/paths");
  15. const workspace_1 = require("../utility/workspace");
  16. function addSnippet(options) {
  17. return (host, context) => {
  18. context.logger.debug('Updating appmodule');
  19. if (options.path === undefined) {
  20. return;
  21. }
  22. const fileRegExp = new RegExp(`^${options.name}.*\\.ts`);
  23. const siblingModules = host
  24. .getDir(options.path)
  25. .subfiles // Find all files that start with the same name, are ts files,
  26. // and aren't spec or module files.
  27. .filter((f) => fileRegExp.test(f) && !/(module|spec)\.ts$/.test(f))
  28. // Sort alphabetically for consistency.
  29. .sort();
  30. if (siblingModules.length === 0) {
  31. // No module to add in.
  32. return;
  33. }
  34. const siblingModulePath = `${options.path}/${siblingModules[0]}`;
  35. const logMessage = 'console.log(`page got message: ${data}`);';
  36. const workerCreationSnippet = core_1.tags.stripIndent `
  37. if (typeof Worker !== 'undefined') {
  38. // Create a new
  39. const worker = new Worker(new URL('./${options.name}.worker', import.meta.url));
  40. worker.onmessage = ({ data }) => {
  41. ${logMessage}
  42. };
  43. worker.postMessage('hello');
  44. } else {
  45. // Web Workers are not supported in this environment.
  46. // You should add a fallback so that your program still executes correctly.
  47. }
  48. `;
  49. // Append the worker creation snippet.
  50. const originalContent = host.readText(siblingModulePath);
  51. host.overwrite(siblingModulePath, originalContent + '\n' + workerCreationSnippet);
  52. return host;
  53. };
  54. }
  55. function default_1(options) {
  56. return async (host) => {
  57. const workspace = await (0, workspace_1.getWorkspace)(host);
  58. if (!options.project) {
  59. throw new schematics_1.SchematicsException('Option "project" is required.');
  60. }
  61. const project = workspace.projects.get(options.project);
  62. if (!project) {
  63. throw new schematics_1.SchematicsException(`Invalid project name (${options.project})`);
  64. }
  65. const projectType = project.extensions['projectType'];
  66. if (projectType !== 'application') {
  67. throw new schematics_1.SchematicsException(`Web Worker requires a project type of "application".`);
  68. }
  69. if (options.path === undefined) {
  70. options.path = (0, workspace_1.buildDefaultPath)(project);
  71. }
  72. const parsedPath = (0, parse_name_1.parseName)(options.path, options.name);
  73. options.name = parsedPath.name;
  74. options.path = parsedPath.path;
  75. const templateSourceWorkerCode = (0, schematics_1.apply)((0, schematics_1.url)('./files/worker'), [
  76. (0, schematics_1.applyTemplates)({ ...options, ...schematics_1.strings }),
  77. (0, schematics_1.move)(parsedPath.path),
  78. ]);
  79. const root = project.root || '';
  80. const templateSourceWorkerConfig = (0, schematics_1.apply)((0, schematics_1.url)('./files/worker-tsconfig'), [
  81. (0, schematics_1.applyTemplates)({
  82. ...options,
  83. relativePathToWorkspaceRoot: (0, paths_1.relativePathToWorkspaceRoot)(root),
  84. }),
  85. (0, schematics_1.move)(root),
  86. ]);
  87. return (0, schematics_1.chain)([
  88. // Add project configuration.
  89. (0, workspace_1.updateWorkspace)((workspace) => {
  90. // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
  91. const project = workspace.projects.get(options.project);
  92. const buildTarget = project.targets.get('build');
  93. const testTarget = project.targets.get('test');
  94. if (!buildTarget) {
  95. throw new Error(`Build target is not defined for this project.`);
  96. }
  97. const workerConfigPath = (0, core_1.join)((0, core_1.normalize)(root), 'tsconfig.worker.json');
  98. (buildTarget.options ??= {}).webWorkerTsConfig ??= workerConfigPath;
  99. if (testTarget) {
  100. (testTarget.options ??= {}).webWorkerTsConfig ??= workerConfigPath;
  101. }
  102. }),
  103. // Create the worker in a sibling module.
  104. options.snippet ? addSnippet(options) : (0, schematics_1.noop)(),
  105. // Add the worker.
  106. (0, schematics_1.mergeWith)(templateSourceWorkerCode),
  107. (0, schematics_1.mergeWith)(templateSourceWorkerConfig),
  108. ]);
  109. };
  110. }