From 5e9a2b1315a09215aa4d0617f78d914b90e7a0c0 Mon Sep 17 00:00:00 2001 From: Cristiano Belloni Date: Wed, 12 Jan 2022 18:15:42 +0000 Subject: [PATCH 01/18] Get dependencies from imports --- .../src/build/dependencyManifest.ts | 34 +++++++++++++++++++ packages/modular-scripts/src/build/index.ts | 4 +++ 2 files changed, 38 insertions(+) create mode 100644 packages/modular-scripts/src/build/dependencyManifest.ts diff --git a/packages/modular-scripts/src/build/dependencyManifest.ts b/packages/modular-scripts/src/build/dependencyManifest.ts new file mode 100644 index 000000000..cbd7c547a --- /dev/null +++ b/packages/modular-scripts/src/build/dependencyManifest.ts @@ -0,0 +1,34 @@ +import * as path from 'path'; +import { Project } from 'ts-morph'; +// import type { CoreProperties } from '@schemastore/package'; +import getModularRoot from '../utils/getModularRoot'; +import getWorkspaceInfo from '../utils/getWorkspaceInfo'; + +// We need to get dependencies from source, since the package.json dependencies could be hosted +function getDependenciesFromSource(workspaceLocation: string) { + const project = new Project(); + project.addSourceFilesAtPaths( + path.join( + getModularRoot(), + workspaceLocation, + 'src/**/*{.d.ts,.ts,.js,.jsx,.tsx}', + ), + ); + // TODO extract the dependency name without the path + return new Set( + project.getSourceFiles().flatMap( + (sourceFile) => + sourceFile + .getImportDeclarations() + .map((declaration) => declaration.getModuleSpecifierValue()) + .filter((dep) => !dep.startsWith('.')), // no relative dependencies + ), + ); +} + +export async function generateDependencyManifest(target: string) { + const workspace = await getWorkspaceInfo(); + const workspaceLocation = workspace[target].location; + const dependencies = getDependenciesFromSource(workspaceLocation); + console.log(dependencies); +} diff --git a/packages/modular-scripts/src/build/index.ts b/packages/modular-scripts/src/build/index.ts index 8aa010d80..d44d1ba12 100644 --- a/packages/modular-scripts/src/build/index.ts +++ b/packages/modular-scripts/src/build/index.ts @@ -25,6 +25,7 @@ import { createEsbuildAssets, esbuildMeasureFileSizesBeforeBuild, } from './esbuildFileSizeReporter'; +import { generateDependencyManifest } from './dependencyManifest'; async function buildApp(target: string) { // True if there's no preference set - or the preference is for webpack. @@ -157,6 +158,9 @@ async function build( await buildPackage(target, preserveModules, includePrivate); } + + // TODO generate a dependency manifest + await generateDependencyManifest(target); } export default actionPreflightCheck(build); From 4a3ec4f34454f5e5245176e017cfaca8a90008fd Mon Sep 17 00:00:00 2001 From: Cristiano Belloni Date: Thu, 13 Jan 2022 12:13:38 +0000 Subject: [PATCH 02/18] Match valid package names --- .../src/build/dependencyManifest.ts | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/packages/modular-scripts/src/build/dependencyManifest.ts b/packages/modular-scripts/src/build/dependencyManifest.ts index cbd7c547a..ee4c08c2e 100644 --- a/packages/modular-scripts/src/build/dependencyManifest.ts +++ b/packages/modular-scripts/src/build/dependencyManifest.ts @@ -4,6 +4,9 @@ import { Project } from 'ts-morph'; import getModularRoot from '../utils/getModularRoot'; import getWorkspaceInfo from '../utils/getWorkspaceInfo'; +const packageNameMatcher = + /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*/; + // We need to get dependencies from source, since the package.json dependencies could be hosted function getDependenciesFromSource(workspaceLocation: string) { const project = new Project(); @@ -14,14 +17,17 @@ function getDependenciesFromSource(workspaceLocation: string) { 'src/**/*{.d.ts,.ts,.js,.jsx,.tsx}', ), ); - // TODO extract the dependency name without the path return new Set( - project.getSourceFiles().flatMap( - (sourceFile) => - sourceFile - .getImportDeclarations() - .map((declaration) => declaration.getModuleSpecifierValue()) - .filter((dep) => !dep.startsWith('.')), // no relative dependencies + project.getSourceFiles().flatMap((sourceFile) => + sourceFile + .getImportDeclarations() + .map( + (declaration) => + declaration + .getModuleSpecifierValue() + .match(packageNameMatcher)?.[0], + ) + .filter(Boolean), ), ); } From 75bd68cd68023fce20755360aa7065821c319073 Mon Sep 17 00:00:00 2001 From: Cristiano Belloni Date: Thu, 13 Jan 2022 14:46:53 +0000 Subject: [PATCH 03/18] Actually get dependencies and write them --- .../src/build/dependencyManifest.ts | 61 +++++++++++++------ packages/modular-scripts/src/build/index.ts | 9 ++- 2 files changed, 50 insertions(+), 20 deletions(-) diff --git a/packages/modular-scripts/src/build/dependencyManifest.ts b/packages/modular-scripts/src/build/dependencyManifest.ts index ee4c08c2e..a40584349 100644 --- a/packages/modular-scripts/src/build/dependencyManifest.ts +++ b/packages/modular-scripts/src/build/dependencyManifest.ts @@ -1,40 +1,67 @@ import * as path from 'path'; +import * as fs from 'fs-extra'; import { Project } from 'ts-morph'; -// import type { CoreProperties } from '@schemastore/package'; +import type { CoreProperties } from '@schemastore/package'; import getModularRoot from '../utils/getModularRoot'; -import getWorkspaceInfo from '../utils/getWorkspaceInfo'; +import getLocation from '../utils/getLocation'; -const packageNameMatcher = +type DependencyManifest = Record; + +const npmPackageMatcher = /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*/; // We need to get dependencies from source, since the package.json dependencies could be hosted function getDependenciesFromSource(workspaceLocation: string) { const project = new Project(); project.addSourceFilesAtPaths( - path.join( - getModularRoot(), - workspaceLocation, - 'src/**/*{.d.ts,.ts,.js,.jsx,.tsx}', - ), + path.join(workspaceLocation, 'src/**/*{.d.ts,.ts,.js,.jsx,.tsx}'), ); - return new Set( + const dependencySet = new Set( project.getSourceFiles().flatMap((sourceFile) => sourceFile .getImportDeclarations() .map( (declaration) => - declaration - .getModuleSpecifierValue() - .match(packageNameMatcher)?.[0], + declaration.getModuleSpecifierValue().match(npmPackageMatcher)?.[0], ) .filter(Boolean), ), - ); + ) as Set; + + console.log(dependencySet); + + return Array.from(dependencySet); } export async function generateDependencyManifest(target: string) { - const workspace = await getWorkspaceInfo(); - const workspaceLocation = workspace[target].location; - const dependencies = getDependenciesFromSource(workspaceLocation); - console.log(dependencies); + // This is based on the assumption that packages can be either contained in the current package.json or hoisted to the root one. + const targetLocation = await getLocation(target); + + const rootPackageJsonDependencies = + ( + fs.readJSONSync( + path.join(getModularRoot(), 'package.json'), + ) as CoreProperties + ).dependencies || {}; + + const targetPackageJsonDependencies = + ( + fs.readJSONSync( + path.join(targetLocation, 'package.json'), + ) as CoreProperties + ).dependencies || {}; + + const manifest = getDependenciesFromSource( + targetLocation, + ).reduce((manifest, depName) => { + const depVersion = + targetPackageJsonDependencies[depName] ?? + rootPackageJsonDependencies[depName]; + if (depVersion) { + manifest[depName] = depVersion; + } + return manifest; + }, {}); + + return manifest; } diff --git a/packages/modular-scripts/src/build/index.ts b/packages/modular-scripts/src/build/index.ts index d44d1ba12..f650104b0 100644 --- a/packages/modular-scripts/src/build/index.ts +++ b/packages/modular-scripts/src/build/index.ts @@ -130,6 +130,12 @@ async function buildApp(target: string) { } } + const dependencyManifest = await generateDependencyManifest(target); + await fs.writeJSON( + path.join(paths.appBuild, 'dependency-manifest.json'), + dependencyManifest, + ); + printFileSizesAfterBuild(assets, previousFileSizes); printHostingInstructions( @@ -158,9 +164,6 @@ async function build( await buildPackage(target, preserveModules, includePrivate); } - - // TODO generate a dependency manifest - await generateDependencyManifest(target); } export default actionPreflightCheck(build); From 78bc775543293d3472fb9d86b19d44bb0c32572e Mon Sep 17 00:00:00 2001 From: Cristiano Belloni Date: Thu, 13 Jan 2022 15:13:21 +0000 Subject: [PATCH 04/18] Remove log --- packages/modular-scripts/src/build/dependencyManifest.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/modular-scripts/src/build/dependencyManifest.ts b/packages/modular-scripts/src/build/dependencyManifest.ts index a40584349..40b214089 100644 --- a/packages/modular-scripts/src/build/dependencyManifest.ts +++ b/packages/modular-scripts/src/build/dependencyManifest.ts @@ -28,8 +28,6 @@ function getDependenciesFromSource(workspaceLocation: string) { ), ) as Set; - console.log(dependencySet); - return Array.from(dependencySet); } From 9a12dc02d2eb9a4e7fa42acaac6bfc5947246a19 Mon Sep 17 00:00:00 2001 From: Cristiano Belloni Date: Thu, 13 Jan 2022 15:35:36 +0000 Subject: [PATCH 05/18] Better comments --- packages/modular-scripts/src/build/dependencyManifest.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/modular-scripts/src/build/dependencyManifest.ts b/packages/modular-scripts/src/build/dependencyManifest.ts index 40b214089..b856294a0 100644 --- a/packages/modular-scripts/src/build/dependencyManifest.ts +++ b/packages/modular-scripts/src/build/dependencyManifest.ts @@ -10,7 +10,7 @@ type DependencyManifest = Record; const npmPackageMatcher = /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*/; -// We need to get dependencies from source, since the package.json dependencies could be hosted +// Get dependencies from import / require declarations, since they could be hoisted to the root workspace function getDependenciesFromSource(workspaceLocation: string) { const project = new Project(); project.addSourceFilesAtPaths( @@ -32,7 +32,8 @@ function getDependenciesFromSource(workspaceLocation: string) { } export async function generateDependencyManifest(target: string) { - // This is based on the assumption that packages can be either contained in the current package.json or hoisted to the root one. + // This is based on the assumption that nested package are not supported, so dependencies can be either declared in the + // target's package.json or hoisted up to the workspace root. const targetLocation = await getLocation(target); const rootPackageJsonDependencies = From 8d11de473776f257e0afb04e18134960c8769736 Mon Sep 17 00:00:00 2001 From: Cristiano Belloni Date: Fri, 14 Jan 2022 11:27:50 +0000 Subject: [PATCH 06/18] Throw if dependency not found in package.json or hoisted in root --- packages/modular-scripts/src/build/dependencyManifest.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/modular-scripts/src/build/dependencyManifest.ts b/packages/modular-scripts/src/build/dependencyManifest.ts index b856294a0..599c058ec 100644 --- a/packages/modular-scripts/src/build/dependencyManifest.ts +++ b/packages/modular-scripts/src/build/dependencyManifest.ts @@ -56,9 +56,12 @@ export async function generateDependencyManifest(target: string) { const depVersion = targetPackageJsonDependencies[depName] ?? rootPackageJsonDependencies[depName]; - if (depVersion) { - manifest[depName] = depVersion; + if (!depVersion) { + throw new Error( + `Package ${depName} imported in ${target} source but not found in package dependencies or hoisted dependencies`, + ); } + manifest[depName] = depVersion; return manifest; }, {}); From c64cbe7e263900f75d0a81ae19b347e1fb659e89 Mon Sep 17 00:00:00 2001 From: Cristiano Belloni Date: Fri, 14 Jan 2022 15:39:32 +0000 Subject: [PATCH 07/18] Add dependencies in package.json --- .../src/build/dependencyManifest.ts | 69 --------------- packages/modular-scripts/src/build/index.ts | 17 +++- .../src/utils/getPackageDependencies.ts | 83 +++++++++++++++++++ 3 files changed, 96 insertions(+), 73 deletions(-) delete mode 100644 packages/modular-scripts/src/build/dependencyManifest.ts create mode 100644 packages/modular-scripts/src/utils/getPackageDependencies.ts diff --git a/packages/modular-scripts/src/build/dependencyManifest.ts b/packages/modular-scripts/src/build/dependencyManifest.ts deleted file mode 100644 index 599c058ec..000000000 --- a/packages/modular-scripts/src/build/dependencyManifest.ts +++ /dev/null @@ -1,69 +0,0 @@ -import * as path from 'path'; -import * as fs from 'fs-extra'; -import { Project } from 'ts-morph'; -import type { CoreProperties } from '@schemastore/package'; -import getModularRoot from '../utils/getModularRoot'; -import getLocation from '../utils/getLocation'; - -type DependencyManifest = Record; - -const npmPackageMatcher = - /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*/; - -// Get dependencies from import / require declarations, since they could be hoisted to the root workspace -function getDependenciesFromSource(workspaceLocation: string) { - const project = new Project(); - project.addSourceFilesAtPaths( - path.join(workspaceLocation, 'src/**/*{.d.ts,.ts,.js,.jsx,.tsx}'), - ); - const dependencySet = new Set( - project.getSourceFiles().flatMap((sourceFile) => - sourceFile - .getImportDeclarations() - .map( - (declaration) => - declaration.getModuleSpecifierValue().match(npmPackageMatcher)?.[0], - ) - .filter(Boolean), - ), - ) as Set; - - return Array.from(dependencySet); -} - -export async function generateDependencyManifest(target: string) { - // This is based on the assumption that nested package are not supported, so dependencies can be either declared in the - // target's package.json or hoisted up to the workspace root. - const targetLocation = await getLocation(target); - - const rootPackageJsonDependencies = - ( - fs.readJSONSync( - path.join(getModularRoot(), 'package.json'), - ) as CoreProperties - ).dependencies || {}; - - const targetPackageJsonDependencies = - ( - fs.readJSONSync( - path.join(targetLocation, 'package.json'), - ) as CoreProperties - ).dependencies || {}; - - const manifest = getDependenciesFromSource( - targetLocation, - ).reduce((manifest, depName) => { - const depVersion = - targetPackageJsonDependencies[depName] ?? - rootPackageJsonDependencies[depName]; - if (!depVersion) { - throw new Error( - `Package ${depName} imported in ${target} source but not found in package dependencies or hoisted dependencies`, - ); - } - manifest[depName] = depVersion; - return manifest; - }, {}); - - return manifest; -} diff --git a/packages/modular-scripts/src/build/index.ts b/packages/modular-scripts/src/build/index.ts index f650104b0..ef16c14fe 100644 --- a/packages/modular-scripts/src/build/index.ts +++ b/packages/modular-scripts/src/build/index.ts @@ -25,7 +25,8 @@ import { createEsbuildAssets, esbuildMeasureFileSizesBeforeBuild, } from './esbuildFileSizeReporter'; -import { generateDependencyManifest } from './dependencyManifest'; +import { getPackageDependencies } from '../utils/getPackageDependencies'; +import type { CoreProperties } from '@schemastore/package'; async function buildApp(target: string) { // True if there's no preference set - or the preference is for webpack. @@ -130,10 +131,18 @@ async function buildApp(target: string) { } } - const dependencyManifest = await generateDependencyManifest(target); + // Add dependencies from source and bundled dependencies to target package.json + const packageDependencies = await getPackageDependencies(target); + const targetPackageJson = (await fs.readJSON( + path.join(targetDirectory, 'package.json'), + )) as CoreProperties; + targetPackageJson.dependencies = packageDependencies; + targetPackageJson.bundledDependencies = Object.keys(packageDependencies); + // Copy package.json over await fs.writeJSON( - path.join(paths.appBuild, 'dependency-manifest.json'), - dependencyManifest, + path.join(paths.appBuild, 'package.json'), + targetPackageJson, + { spaces: 2 }, ); printFileSizesAfterBuild(assets, previousFileSizes); diff --git a/packages/modular-scripts/src/utils/getPackageDependencies.ts b/packages/modular-scripts/src/utils/getPackageDependencies.ts new file mode 100644 index 000000000..dfe2a8842 --- /dev/null +++ b/packages/modular-scripts/src/utils/getPackageDependencies.ts @@ -0,0 +1,83 @@ +import * as path from 'path'; +import * as fs from 'fs-extra'; +import { Project } from 'ts-morph'; +import type { CoreProperties } from '@schemastore/package'; +import getModularRoot from './getModularRoot'; +import getLocation from './getLocation'; +import getWorkspaceInfo from './getWorkspaceInfo'; + +type DependencyManifest = NonNullable; + +const npmPackageMatcher = + /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*/; + +/* Get dependencies from import / require declarations, since they could be hoisted to the root workspace. Exclude test files. */ +function getDependenciesFromSource(workspaceLocation: string) { + const project = new Project(); + project.addSourceFilesAtPaths( + path.join(workspaceLocation, 'src/**/!(*.test){.d.ts,.ts,.js,.jsx,.tsx}'), + ); + + const dependencySet = new Set( + project + .getSourceFiles() + .flatMap((sourceFile) => + sourceFile + .getImportDeclarations() + .map( + (declaration) => + npmPackageMatcher.exec( + declaration.getModuleSpecifierValue(), + )?.[0], + ), + ) + .filter(Boolean), + ) as Set; + + return Array.from(dependencySet); +} + +export async function getPackageDependencies( + target: string, +): Promise { + /* This function is based on the assumption that nested package are not supported, so dependencies can be either declared in the + * target's package.json or hoisted up to the workspace root. + */ + const targetLocation = await getLocation(target); + const workspaceInfo = getWorkspaceInfo(); + + const rootPackageJsonDependencies = + ( + fs.readJSONSync( + path.join(getModularRoot(), 'package.json'), + ) as CoreProperties + ).dependencies || {}; + + const targetPackageJsonDependencies = + ( + fs.readJSONSync( + path.join(targetLocation, 'package.json'), + ) as CoreProperties + ).dependencies || {}; + + /* Get regular dependencies from package.json (regular) or root package.json (hoisted) + * Exclude workspace dependencies. Error if a dependency is imported in the source code + * but not specified in any of the package.jsons + */ + const manifest = getDependenciesFromSource(targetLocation) + .filter((depName) => !(depName in workspaceInfo)) + .reduce((manifest, depName) => { + const depVersion = + targetPackageJsonDependencies[depName] ?? + rootPackageJsonDependencies[depName]; + if (!depVersion) { + throw new Error( + `Package ${depName} imported in ${target} source but not found in package dependencies or hoisted dependencies`, + ); + } + manifest[depName] = depVersion; + return manifest; + }, {}); + + return manifest; +} From 331c1a9a4ad69e76215e6fafe4faab12b70284a9 Mon Sep 17 00:00:00 2001 From: Cristiano Belloni Date: Fri, 14 Jan 2022 15:53:45 +0000 Subject: [PATCH 08/18] Update snapshots --- packages/modular-scripts/src/__tests__/app.test.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/modular-scripts/src/__tests__/app.test.ts b/packages/modular-scripts/src/__tests__/app.test.ts index 8aa70d982..f23e226e4 100644 --- a/packages/modular-scripts/src/__tests__/app.test.ts +++ b/packages/modular-scripts/src/__tests__/app.test.ts @@ -83,6 +83,7 @@ describe('when working with a NODE_ENV app', () => { ├─ logo192.png #1nez7vk ├─ logo512.png #1hwqvcc ├─ manifest.json #19gah8o + ├─ package.json ├─ robots.txt #1sjb8b3 └─ static └─ js @@ -138,6 +139,7 @@ describe('When working with a nested app', () => { ├─ logo192.png #1nez7vk ├─ logo512.png #1hwqvcc ├─ manifest.json #19gah8o + ├─ package.json ├─ robots.txt #1sjb8b3 └─ static ├─ css @@ -355,6 +357,7 @@ describe('when working with an app', () => { ├─ logo192.png #1nez7vk ├─ logo512.png #1hwqvcc ├─ manifest.json #19gah8o + ├─ package.json ├─ robots.txt #1sjb8b3 └─ static ├─ css From df53d74517e3bebe40185b215f35832caf7dc6fe Mon Sep 17 00:00:00 2001 From: Cristiano Belloni Date: Fri, 14 Jan 2022 16:13:57 +0000 Subject: [PATCH 09/18] Update esbuild snapshots --- packages/modular-scripts/src/__tests__/app.esbuild.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/modular-scripts/src/__tests__/app.esbuild.test.ts b/packages/modular-scripts/src/__tests__/app.esbuild.test.ts index e27324250..302929bbc 100644 --- a/packages/modular-scripts/src/__tests__/app.esbuild.test.ts +++ b/packages/modular-scripts/src/__tests__/app.esbuild.test.ts @@ -84,6 +84,7 @@ describe('when working with an app', () => { ├─ logo192.png #1nez7vk ├─ logo512.png #1hwqvcc ├─ manifest.json #19gah8o + ├─ package.json ├─ robots.txt #1sjb8b3 └─ static ├─ css From aa07cd905f3021ebee5b91048cf8b41a73fff79c Mon Sep 17 00:00:00 2001 From: Cristiano Belloni Date: Mon, 17 Jan 2022 15:18:14 +0000 Subject: [PATCH 10/18] Select fields for package.json --- packages/modular-scripts/src/build/index.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/modular-scripts/src/build/index.ts b/packages/modular-scripts/src/build/index.ts index ef16c14fe..14ae31921 100644 --- a/packages/modular-scripts/src/build/index.ts +++ b/packages/modular-scripts/src/build/index.ts @@ -138,10 +138,20 @@ async function buildApp(target: string) { )) as CoreProperties; targetPackageJson.dependencies = packageDependencies; targetPackageJson.bundledDependencies = Object.keys(packageDependencies); - // Copy package.json over + // Copy selected fields of package.json over await fs.writeJSON( path.join(paths.appBuild, 'package.json'), - targetPackageJson, + { + name: targetPackageJson.name, + version: targetPackageJson.version, + main: targetPackageJson.main, + license: targetPackageJson.license, + modular: targetPackageJson.modular, + files: targetPackageJson.files, + module: targetPackageJson.module, + typings: targetPackageJson.typings, + dependencies: targetPackageJson.dependencies, + }, { spaces: 2 }, ); From 13f5b83b6b64786e72d1f35c21e17dae3e64460d Mon Sep 17 00:00:00 2001 From: Cristiano Belloni Date: Mon, 17 Jan 2022 15:26:04 +0000 Subject: [PATCH 11/18] Upgrade ts-morph --- packages/modular-scripts/package.json | 2 +- packages/modular-scripts/src/build/index.ts | 1 - yarn.lock | 57 ++++++++++++--------- 3 files changed, 35 insertions(+), 25 deletions(-) diff --git a/packages/modular-scripts/package.json b/packages/modular-scripts/package.json index 9f4be9590..6dde7b7fe 100644 --- a/packages/modular-scripts/package.json +++ b/packages/modular-scripts/package.json @@ -112,7 +112,7 @@ "terser-webpack-plugin": "4.2.3", "tmp": "^0.2.1", "ts-jest": "26.5.6", - "ts-morph": "^11.0.3", + "ts-morph": "^13.0.1", "update-notifier": "5.1.0", "url-loader": "4.1.1", "webpack": "4.46.0", diff --git a/packages/modular-scripts/src/build/index.ts b/packages/modular-scripts/src/build/index.ts index 14ae31921..90551d23f 100644 --- a/packages/modular-scripts/src/build/index.ts +++ b/packages/modular-scripts/src/build/index.ts @@ -83,7 +83,6 @@ async function buildApp(target: string) { '../esbuild-scripts/build' ); const result = await buildEsbuildApp(target, paths); - assets = createEsbuildAssets(paths, result); } else { // create-react-app doesn't support plain module outputs yet, diff --git a/yarn.lock b/yarn.lock index c7b4970c8..3da7b5f6c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2373,12 +2373,12 @@ resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== -"@ts-morph/common@~0.10.1": - version "0.10.1" - resolved "https://registry.yarnpkg.com/@ts-morph/common/-/common-0.10.1.tgz#be15b9ab13a32bbc1f6a6bd7dc056b2247b272eb" - integrity sha512-rKN/VtZUUlW4M+6vjLFSaFc1Z9sK+1hh0832ucPtPkXqOw/mSWE80Lau4z2zTPNTqtxAjfZbvKpQcEwJy0KIEg== +"@ts-morph/common@~0.12.2": + version "0.12.2" + resolved "https://registry.yarnpkg.com/@ts-morph/common/-/common-0.12.2.tgz#61d07a47d622d231e833c44471ab306faaa41aed" + integrity sha512-m5KjptpIf1K0t0QL38uE+ol1n+aNn9MgRq++G3Zym1FlqfN+rThsXlp3cAgib14pIeXF7jk3UtJQOviwawFyYg== dependencies: - fast-glob "^3.2.5" + fast-glob "^3.2.7" minimatch "^3.0.4" mkdirp "^1.0.4" path-browserify "^1.0.1" @@ -4459,10 +4459,12 @@ coa@^2.0.2: chalk "^2.4.1" q "^1.1.2" -code-block-writer@^10.1.1: - version "10.1.1" - resolved "https://registry.yarnpkg.com/code-block-writer/-/code-block-writer-10.1.1.tgz#ad5684ed4bfb2b0783c8b131281ae84ee640a42f" - integrity sha512-67ueh2IRGst/51p0n6FvPrnRjAGHY5F8xdjkgrYE7DDzpJe6qA07RYQ9VcoUeo5ATOjSOiWpSL3SWBRRbempMw== +code-block-writer@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/code-block-writer/-/code-block-writer-11.0.0.tgz#5956fb186617f6740e2c3257757fea79315dd7d4" + integrity sha512-GEqWvEWWsOvER+g9keO4ohFoD3ymwyCnqY3hoTr7GZipYFwEhMHJw+TtV0rfgRhNImM6QWZGO2XYjlJVyYT62w== + dependencies: + tslib "2.3.1" collect-v8-coverage@^1.0.0: version "1.0.1" @@ -6655,7 +6657,7 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.1.1, fast-glob@^3.2.5: +fast-glob@^3.1.1: version "3.2.7" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== @@ -6666,6 +6668,17 @@ fast-glob@^3.1.1, fast-glob@^3.2.5: merge2 "^1.3.0" micromatch "^4.0.4" +fast-glob@^3.2.7: + version "3.2.11" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" + integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -12871,13 +12884,13 @@ ts-jest@26.5.6: semver "7.x" yargs-parser "20.x" -ts-morph@^11.0.3: - version "11.0.3" - resolved "https://registry.yarnpkg.com/ts-morph/-/ts-morph-11.0.3.tgz#01a92b3c2b5a48ccdf318ec90864229b8061d056" - integrity sha512-ymuPkndv9rzqTLiHWMkVrFXWcN4nBiBGhRP/kTC9F5amAAl7BNLfyrsTzMD1o9A0zishKoF1KQT/0yyFhJnPgA== +ts-morph@^13.0.1: + version "13.0.2" + resolved "https://registry.yarnpkg.com/ts-morph/-/ts-morph-13.0.2.tgz#55546023493ef82389d9e4f28848a556c784bac4" + integrity sha512-SjeeHaRf/mFsNeR3KTJnx39JyEOzT4e+DX28gQx5zjzEOuFs2eGrqeN2PLKs/+AibSxPmzV7RD8nJVKmFJqtLA== dependencies: - "@ts-morph/common" "~0.10.1" - code-block-writer "^10.1.1" + "@ts-morph/common" "~0.12.2" + code-block-writer "^11.0.0" ts-node@10.4.0: version "10.4.0" @@ -12912,16 +12925,16 @@ tsconfig-paths@^3.11.0: minimist "^1.2.0" strip-bom "^3.0.0" +tslib@2.3.1, tslib@^2.0.3: + version "2.3.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" + integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== + tslib@^1.8.1, tslib@^1.9.3: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.3: - version "2.3.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" - integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== - tslib@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" @@ -13337,10 +13350,8 @@ watchpack@^1.7.4: resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.5.tgz#1267e6c55e0b9b5be44c2023aed5437a2c26c453" integrity sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ== dependencies: - chokidar "^3.4.1" graceful-fs "^4.1.2" neo-async "^2.5.0" - watchpack-chokidar2 "^2.0.1" optionalDependencies: chokidar "^3.4.1" watchpack-chokidar2 "^2.0.1" From 75323c1e050a41f8469d79467266b320dbb9e545 Mon Sep 17 00:00:00 2001 From: Cristiano Belloni Date: Mon, 17 Jan 2022 15:41:00 +0000 Subject: [PATCH 12/18] remove main, files, typings --- packages/modular-scripts/src/build/index.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/modular-scripts/src/build/index.ts b/packages/modular-scripts/src/build/index.ts index 90551d23f..f8ebe3944 100644 --- a/packages/modular-scripts/src/build/index.ts +++ b/packages/modular-scripts/src/build/index.ts @@ -143,12 +143,9 @@ async function buildApp(target: string) { { name: targetPackageJson.name, version: targetPackageJson.version, - main: targetPackageJson.main, license: targetPackageJson.license, modular: targetPackageJson.modular, - files: targetPackageJson.files, module: targetPackageJson.module, - typings: targetPackageJson.typings, dependencies: targetPackageJson.dependencies, }, { spaces: 2 }, From 63abb2e18114e894cc3bdd5b31d8c023193d16ac Mon Sep 17 00:00:00 2001 From: Cristiano Belloni Date: Mon, 17 Jan 2022 15:49:45 +0000 Subject: [PATCH 13/18] Bump ts-morph --- packages/modular-scripts/package.json | 2 +- yarn.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/modular-scripts/package.json b/packages/modular-scripts/package.json index 6dde7b7fe..fe9ca783a 100644 --- a/packages/modular-scripts/package.json +++ b/packages/modular-scripts/package.json @@ -112,7 +112,7 @@ "terser-webpack-plugin": "4.2.3", "tmp": "^0.2.1", "ts-jest": "26.5.6", - "ts-morph": "^13.0.1", + "ts-morph": "^13.0.2", "update-notifier": "5.1.0", "url-loader": "4.1.1", "webpack": "4.46.0", diff --git a/yarn.lock b/yarn.lock index 3da7b5f6c..ae22ab199 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12884,7 +12884,7 @@ ts-jest@26.5.6: semver "7.x" yargs-parser "20.x" -ts-morph@^13.0.1: +ts-morph@^13.0.2: version "13.0.2" resolved "https://registry.yarnpkg.com/ts-morph/-/ts-morph-13.0.2.tgz#55546023493ef82389d9e4f28848a556c784bac4" integrity sha512-SjeeHaRf/mFsNeR3KTJnx39JyEOzT4e+DX28gQx5zjzEOuFs2eGrqeN2PLKs/+AibSxPmzV7RD8nJVKmFJqtLA== From b531e106e2382c1c88df690313fc207265d187e3 Mon Sep 17 00:00:00 2001 From: Cristiano Belloni Date: Mon, 17 Jan 2022 16:51:30 +0000 Subject: [PATCH 14/18] Add tests --- .../modular-scripts/src/__tests__/app.test.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/packages/modular-scripts/src/__tests__/app.test.ts b/packages/modular-scripts/src/__tests__/app.test.ts index f23e226e4..7eccf9eaf 100644 --- a/packages/modular-scripts/src/__tests__/app.test.ts +++ b/packages/modular-scripts/src/__tests__/app.test.ts @@ -15,6 +15,7 @@ import getModularRoot from '../utils/getModularRoot'; import puppeteer from 'puppeteer'; import { startApp, DevServer } from './start-app'; +import type { CoreProperties } from '@schemastore/package'; // eslint-disable-next-line @typescript-eslint/unbound-method const { getNodeText } = queries; @@ -394,6 +395,22 @@ describe('when working with an app', () => { ).toMatchSnapshot(); }); + it('can generate a package.json', async () => { + const packageJson = JSON.parse( + String( + await fs.readFile( + path.join(modularRoot, 'dist', 'sample-app', 'package.json'), + ), + ), + ) as CoreProperties; + + expect(packageJson.name).toBe('sample-app'); + expect(packageJson.version).toBe('0.1.0'); + expect(packageJson.modular).toStrictEqual({ type: 'app' }); + expect(packageJson.dependencies?.react).toBeTruthy(); + expect(packageJson.dependencies?.['react-dom']).toBeTruthy(); + }); + it('can generate a index.html', async () => { expect( prettier.format( From 3e6d91e4b13c0ef12e6923bc171d2bbb1a07c19b Mon Sep 17 00:00:00 2001 From: Cristiano Belloni Date: Tue, 18 Jan 2022 16:49:31 +0000 Subject: [PATCH 15/18] remove module field --- packages/modular-scripts/src/build/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/modular-scripts/src/build/index.ts b/packages/modular-scripts/src/build/index.ts index f8ebe3944..787c68552 100644 --- a/packages/modular-scripts/src/build/index.ts +++ b/packages/modular-scripts/src/build/index.ts @@ -145,7 +145,6 @@ async function buildApp(target: string) { version: targetPackageJson.version, license: targetPackageJson.license, modular: targetPackageJson.modular, - module: targetPackageJson.module, dependencies: targetPackageJson.dependencies, }, { spaces: 2 }, From 29313837a00ccdd33d126960c82e3e37a5bdcfd3 Mon Sep 17 00:00:00 2001 From: Cristiano Belloni Date: Tue, 18 Jan 2022 16:53:13 +0000 Subject: [PATCH 16/18] Create nervous-islands-taste.md --- .changeset/nervous-islands-taste.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/nervous-islands-taste.md diff --git a/.changeset/nervous-islands-taste.md b/.changeset/nervous-islands-taste.md new file mode 100644 index 000000000..bd95ee2dd --- /dev/null +++ b/.changeset/nervous-islands-taste.md @@ -0,0 +1,6 @@ +--- +"modular-scripts": minor +--- + +Generate dependency manifest (package.json) for apps. This includes all the dependencies, either installed via the package's `package.json` or hoisted to the root's `package.json`. +If a dependency is imported in code but not specified in the `package.json`s, the app will not build anymore. From 7835e8ea4910ee547266305ac985f5f7b515b612 Mon Sep 17 00:00:00 2001 From: Cristiano Belloni Date: Tue, 18 Jan 2022 17:52:21 +0000 Subject: [PATCH 17/18] Fix deprecation --- .../config/webpackDevServer.config.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/modular-scripts/react-scripts/config/webpackDevServer.config.js b/packages/modular-scripts/react-scripts/config/webpackDevServer.config.js index 79505343d..161299c18 100644 --- a/packages/modular-scripts/react-scripts/config/webpackDevServer.config.js +++ b/packages/modular-scripts/react-scripts/config/webpackDevServer.config.js @@ -94,31 +94,29 @@ module.exports = function (port, proxy, allowedHost) { }, // `proxy` is run between `before` and `after` `webpack-dev-server` hooks proxy, - onBeforeSetupMiddleware(server) { + setupMiddlewares(middlewares, server) { const app = server.app; // Keep `evalSourceMapMiddleware` and `errorOverlayMiddleware` // middlewares before `redirectServedPath` otherwise will not have any effect // This lets us fetch source contents from webpack for the error overlay - app.use(evalSourceMapMiddleware(server)); + middlewares.unshift(evalSourceMapMiddleware(server)); // This lets us open files from the runtime error overlay. - app.use(errorOverlayMiddleware()); + middlewares.unshift(errorOverlayMiddleware()); if (fs.existsSync(paths.proxySetup)) { // This registers user provided middleware for proxy reasons require(paths.proxySetup)(app); } - }, - onAfterSetupMiddleware(server) { - const app = server.app; + // Redirect to `PUBLIC_URL` or `homepage` from `package.json` if url not match - app.use(redirectServedPath(paths.publicUrlOrPath)); + middlewares.push(redirectServedPath(paths.publicUrlOrPath)); // This service worker file is effectively a 'no-op' that will reset any // previous service worker registered for the same host:port combination. // We do this in development to avoid hitting the production cache if // it used the same host and port. // https://github.com/facebook/create-react-app/issues/2272#issuecomment-302832432 - app.use(noopServiceWorkerMiddleware(paths.publicUrlOrPath)); + middlewares.push(noopServiceWorkerMiddleware(paths.publicUrlOrPath)); }, }; }; From 50c93b3be3278cae12b07c9b47c4a099a42a9c5e Mon Sep 17 00:00:00 2001 From: Cristiano Belloni Date: Tue, 18 Jan 2022 18:17:00 +0000 Subject: [PATCH 18/18] Revert "Fix deprecation" This reverts commit 7835e8ea4910ee547266305ac985f5f7b515b612. --- .../config/webpackDevServer.config.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/modular-scripts/react-scripts/config/webpackDevServer.config.js b/packages/modular-scripts/react-scripts/config/webpackDevServer.config.js index 161299c18..79505343d 100644 --- a/packages/modular-scripts/react-scripts/config/webpackDevServer.config.js +++ b/packages/modular-scripts/react-scripts/config/webpackDevServer.config.js @@ -94,29 +94,31 @@ module.exports = function (port, proxy, allowedHost) { }, // `proxy` is run between `before` and `after` `webpack-dev-server` hooks proxy, - setupMiddlewares(middlewares, server) { + onBeforeSetupMiddleware(server) { const app = server.app; // Keep `evalSourceMapMiddleware` and `errorOverlayMiddleware` // middlewares before `redirectServedPath` otherwise will not have any effect // This lets us fetch source contents from webpack for the error overlay - middlewares.unshift(evalSourceMapMiddleware(server)); + app.use(evalSourceMapMiddleware(server)); // This lets us open files from the runtime error overlay. - middlewares.unshift(errorOverlayMiddleware()); + app.use(errorOverlayMiddleware()); if (fs.existsSync(paths.proxySetup)) { // This registers user provided middleware for proxy reasons require(paths.proxySetup)(app); } - + }, + onAfterSetupMiddleware(server) { + const app = server.app; // Redirect to `PUBLIC_URL` or `homepage` from `package.json` if url not match - middlewares.push(redirectServedPath(paths.publicUrlOrPath)); + app.use(redirectServedPath(paths.publicUrlOrPath)); // This service worker file is effectively a 'no-op' that will reset any // previous service worker registered for the same host:port combination. // We do this in development to avoid hitting the production cache if // it used the same host and port. // https://github.com/facebook/create-react-app/issues/2272#issuecomment-302832432 - middlewares.push(noopServiceWorkerMiddleware(paths.publicUrlOrPath)); + app.use(noopServiceWorkerMiddleware(paths.publicUrlOrPath)); }, }; };