Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite [resolution] dependencies from lockfile version #1693

Merged
merged 93 commits into from
May 20, 2022
Merged
Show file tree
Hide file tree
Changes from 90 commits
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
c5c50db
Bring webpack configuration to a valid (but not working) state
Feb 18, 2022
f139c67
webpack build working
Feb 21, 2022
a2c91cb
Remove sourcemap obsolete flag
Feb 21, 2022
3d3352d
Redo ForkTsCheckerWebpackPlugin conf
Feb 21, 2022
5fcacfa
Fix stats type mismatch
Feb 21, 2022
8fb8342
start.js
Feb 22, 2022
b20e694
dev server working but trying to typecheck node_modules
Feb 23, 2022
bdfd0ec
webpack start is working
Feb 23, 2022
8986bd9
Change css minimizer to remove deprecation
Feb 23, 2022
9bd0894
Remove diagnostics
Feb 23, 2022
510fb6b
Update snapshots
Feb 24, 2022
92597a4
Support new version of minimize
Feb 24, 2022
8bf2aea
Add explaining comment
Feb 24, 2022
c6df324
Merge remote-tracking branch 'origin/main' into feature/experiment-we…
Feb 28, 2022
5a340d0
Update yarn.lock
Feb 28, 2022
3122acf
Merge remote-tracking branch 'origin/main' into feature/experiment-we…
Mar 4, 2022
1f7a830
Merge remote-tracking branch 'origin/main' into feature/experiment-we…
Mar 7, 2022
8b1f89b
Merge remote-tracking branch 'origin/main' into feature/experiment-we…
Mar 8, 2022
f075c72
Update snapshots
Mar 8, 2022
7c98350
Update all snapshots
Mar 8, 2022
5f3c001
Update snapshot hash
Mar 8, 2022
7b45909
Add missing quotes
Mar 8, 2022
f97c6f2
Merge branch 'main' into feature/experiment-webpack-5
cristiano-belloni Mar 11, 2022
bc9cb4c
Remove unwanted media dist files
Mar 11, 2022
87964dd
remove tsbuildinfo
Mar 11, 2022
187f866
Merge remote-tracking branch 'origin/main' into feature/experiment-we…
Mar 11, 2022
e1abbef
Make test names decoupled from hashes
Mar 14, 2022
8816b88
Update test snapshots
Mar 14, 2022
e5d772f
Create silver-dolphins-remember.md
cristiano-belloni Mar 16, 2022
51e770e
Enter pre-release mode
Mar 16, 2022
b16fae1
Merge remote-tracking branch 'origin/main' into release/webpack-5
Mar 17, 2022
681ab74
Merge remote-tracking branch 'origin/main' into feature/experiment-we…
Mar 17, 2022
07052ac
Remove requireEnsure
Mar 21, 2022
55df9e0
Merge remote-tracking branch 'origin/main' into feature/experiment-we…
Mar 22, 2022
76ce1bb
Merge remote-tracking branch 'origin/main' into release/webpack-5
Mar 25, 2022
dc846d8
Regenerate pre.json
Mar 25, 2022
43c42b7
remove workflow rule
Mar 25, 2022
bd5e86b
Merge remote-tracking branch 'origin/main' into feature/experiment-we…
Mar 25, 2022
50332fd
Merge remote-tracking branch 'origin/main' into release/webpack-5
Mar 28, 2022
fb7db88
Update pre.json
Mar 28, 2022
5a6dfdc
Merge remote-tracking branch 'origin/main' into feature/experiment-we…
Mar 28, 2022
47e1ec4
Update snapshots
Mar 28, 2022
64f46f7
Update build snapshots
Mar 28, 2022
41ded67
Update browser versions
Mar 28, 2022
b2ca58b
Merge pull request #1421 from jpmorganchase/feature/experiment-webpack-5
cristiano-belloni Mar 29, 2022
8cfe64f
Version Packages (alpha-webpack5)
github-actions[bot] Mar 29, 2022
d8562e6
Merge pull request #1521 from jpmorganchase/changeset-release/release…
cristiano-belloni Mar 29, 2022
4f1af82
Revert "Revert engine range (#1518)"
Apr 5, 2022
d2aacf6
Revert "fix node-12 incompatible javascript (#1517)"
Apr 5, 2022
d2b10e9
Remove node 12 support
Apr 5, 2022
69da976
Add changeset
Apr 5, 2022
c40158b
Add node 18 in CI
Apr 5, 2022
074bff4
Revert "Add node 18 in CI"
Apr 5, 2022
4baca0a
Hardcode node to v14
Apr 6, 2022
9f48679
support node 16 explicitly and run test workflow against target node …
LukeSheard Apr 6, 2022
8115519
fix node versions so that tests run
LukeSheard Apr 6, 2022
8b3f1f5
Create dirty-mugs-double.md
LukeSheard Apr 6, 2022
8901b9f
fix node versions so that tests run and remove 15 since it's unsupported
LukeSheard Apr 6, 2022
0a0bc65
Merge remote-tracking branch 'origin/bugfix/workflow-node-version' in…
Apr 7, 2022
4abf766
Raise version to be compatible with eslint
Apr 7, 2022
4f9cba9
Version Packages (alpha-webpack5)
github-actions[bot] Apr 7, 2022
a31fb3f
Merge pull request #1554 from jpmorganchase/changeset-release/release…
cristiano-belloni Apr 8, 2022
af674c5
Support for esm-view type in react scripts
Apr 26, 2022
d6d2e8c
Add esm-view into modular types
Apr 26, 2022
49c0604
Better names for isView + activate esm-views in start
Apr 26, 2022
69c480c
Update tests
Apr 26, 2022
93e0adb
Add tests and way of adding esm-view
Apr 26, 2022
a60bec5
Better comments/names
Apr 26, 2022
b0ccaf4
Merge remote-tracking branch 'origin/main' into feature/esm-views
May 3, 2022
8c0a688
Add esm-view type
May 4, 2022
375c7e8
Add package modular-template-esm-view
May 4, 2022
309cf20
Fix logger error
May 4, 2022
4e46075
fix esm view tests
May 4, 2022
865b80f
Fix app tests
May 4, 2022
f168606
Fix view tests
May 4, 2022
2130f56
Fix build tests
May 4, 2022
7fa41ae
Remove residual changelogs
May 4, 2022
d34acec
Fix app node env tests
May 4, 2022
c189293
Fix WorkspaceInfo test
May 5, 2022
455cb57
Merge remote-tracking branch 'origin/main' into feature/esm-views
May 5, 2022
c051e92
Create proud-starfishes-stare.md
cristiano-belloni May 5, 2022
141e960
Extract resolutions from lockfile and use them to build esbuild
May 6, 2022
e4e72d4
Extract resolutions from lockfile and use them to build Webpack
May 6, 2022
95d70c4
Write tests for resolutions
May 6, 2022
dfa39c8
Fix tests
May 6, 2022
5167a1b
Create tender-shirts-turn.md
cristiano-belloni May 11, 2022
bd96695
Merge remote-tracking branch 'origin/main' into feature/lockfile-driv…
May 12, 2022
962698a
Update test snapshots
May 12, 2022
5034fd9
Update rewriteDependenciesPlugin.ts
cristiano-belloni May 12, 2022
17809f4
Use resolution if no version
May 12, 2022
15fbb13
Use reactdom version if present
May 16, 2022
2cc2818
Merge remote-tracking branch 'origin/main' into feature/lockfile-driv…
May 16, 2022
a8f0a22
Merge api.ts
May 16, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/tender-shirts-turn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"modular-scripts": patch
---

Adds the [resolution] tag in the CDN template to point to the pinned version as resolved from yarn.lock.
3 changes: 2 additions & 1 deletion packages/modular-scripts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@
"global-modules": "2.0.0",
"globby": "11.0.4",
"gzip-size": "6.0.0",
"html-webpack-plugin": "5.5.0",
"html-minifier-terser": "6.1.0",
"html-webpack-plugin": "5.5.0",
"is-ci": "2.0.0",
"is-root": "2.1.0",
"jest": "26.6.3",
Expand Down Expand Up @@ -104,6 +104,7 @@
"semver": "7.3.7",
"semver-regex": "3.1.3",
"shell-quote": "1.7.3",
"snyk-nodejs-lockfile-parser": "^1.38.0",
"source-map-support": "0.5.21",
"strip-ansi": "6.0.0",
"style-loader": "3.3.1",
Expand Down
31 changes: 23 additions & 8 deletions packages/modular-scripts/react-scripts/config/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ const { externalDependencies } = process.env.MODULAR_PACKAGE_DEPS
? JSON.parse(process.env.MODULAR_PACKAGE_DEPS)
: {};

const { externalResolutions } = process.env.MODULAR_PACKAGE_RESOLUTIONS
? JSON.parse(process.env.MODULAR_PACKAGE_RESOLUTIONS)
: {};

// Source maps are resource heavy and can cause out of memory issue for large source files.
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';

Expand Down Expand Up @@ -77,10 +81,13 @@ module.exports = function (webpackEnv) {
if (externalDependencies.react && isEsmViewDevelopment) {
externalDependencies['react-dom'] = externalDependencies.react;
}
if (externalResolutions.react && isEsmViewDevelopment) {
externalResolutions['react-dom'] = externalResolutions.react;
}

// Create a map of external dependencies if we're building a ESM view
const dependencyMap = isEsmView
? createExternalDependenciesMap(externalDependencies)
? createExternalDependenciesMap(externalDependencies, externalResolutions)
: {};

// Variable used for enabling profiling in Production
Expand Down Expand Up @@ -735,20 +742,28 @@ module.exports = function (webpackEnv) {
return webpackConfig;
};

function createExternalDependenciesMap(externalDependencies) {
function createExternalDependenciesMap(
externalDependencies,
externalResolutions,
) {
const externalCdnTemplate =
process.env.EXTERNAL_CDN_TEMPLATE ||
'https://cdn.skypack.dev/[name]@[version]';

return Object.entries(externalDependencies).reduce(
(acc, [name, version]) => ({
return Object.entries(externalDependencies).reduce((acc, [name, version]) => {
if (!externalResolutions[name]) {
throw new Error(
`Dependency ${name} found in package.json but not in lockfile. Have you installed your dependencies?`,
);
}
return {
...acc,
[name]: externalCdnTemplate
.replace('[name]', name)
.replace('[version]', version),
}),
{},
);
.replace('[version]', version || externalResolutions[name])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a case where version would not be defined?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a case where version would not be defined?

Good question. There is at the moment, because we relaxed our criteria to only warn in case a version is nor present in (on e of the) package.json. The reason is that some widely used libraries rely on transitive dependencies (dm me for more info)

.replace('[resolution]', externalResolutions[name]),
};
}, {});
}

const packageRegex =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12872,6 +12872,80 @@ export { e as default };
"
`;

exports[`modular-scripts WHEN building a esm-view with resolutions THEN rewrites the dependencies 1`] = `
"import * as e from \\"https://mycustomcdn.net/react@17.0.2\\";
import r from \\"https://mycustomcdn.net/lodash@4.17.21/get\\";
import t from \\"https://mycustomcdn.net/lodash.merge@4.6.2\\";
import { difference as i } from \\"https://mycustomcdn.net/lodash@4.17.21\\";
function m() {
return e.createElement(
\\"div\\",
null,
e.createElement(
\\"pre\\",
null,
JSON.stringify({ get: r, merge: t, difference: i })
)
);
}
export { m as default };
//# sourceMappingURL=/static/js/index-IDYQ56WQ.js.map
"
`;

exports[`modular-scripts WHEN building a esm-view with resolutions and webpack THEN rewrites the dependencies 1`] = `
"import * as e from \\"https://mycustomcdn.net/react@17.0.2\\";
import * as t from \\"https://mycustomcdn.net/lodash@4.17.21/get\\";
import * as r from \\"https://mycustomcdn.net/lodash.merge@4.6.2\\";
import * as n from \\"https://mycustomcdn.net/lodash@4.17.21\\";
var a = {
d: (e, t) => {
for (var r in t)
a.o(t, r) &&
!a.o(e, r) &&
Object.defineProperty(e, r, { enumerable: !0, get: t[r] });
},
o: (e, t) => Object.prototype.hasOwnProperty.call(e, t),
},
o = {};
a.d(o, { Z: () => s });
const d = ((e) => {
var t = {};
return a.d(t, e), t;
})({ createElement: () => e.createElement });
const c = ((e) => {
var t = {};
return a.d(t, e), t;
})({ default: () => t.default });
const f = ((e) => {
var t = {};
return a.d(t, e), t;
})({ default: () => r.default });
const m = ((e) => {
var t = {};
return a.d(t, e), t;
})({ difference: () => n.difference });
function s() {
return d.createElement(
\\"div\\",
null,
d.createElement(
\\"pre\\",
null,
JSON.stringify({
get: c.default,
merge: f.default,
difference: m.difference,
})
)
);
}
var l = o.Z;
export { l as default };
//# sourceMappingURL=main.219bc98b.js.map
"
`;

exports[`modular-scripts WHEN building a esm-view with various kinds of package dependencies THEN rewrites the dependencies 1`] = `
"import * as e from \\"https://mycustomcdn.net/react?version=17.0.2\\";
import r from \\"https://mycustomcdn.net/lodash?version=^4.17.21/get\\";
Expand Down
164 changes: 158 additions & 6 deletions packages/modular-scripts/src/__tests__/esmView.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ describe('modular-scripts', () => {
expect(tree(path.join(modularRoot, 'dist', 'sample-esm-view')))
.toMatchInlineSnapshot(`
"sample-esm-view
├─ index.html #17sfbiz
├─ index.html #1t5wlh8
├─ package.json
└─ static
└─ js
Expand All @@ -205,7 +205,7 @@ describe('modular-scripts', () => {
expect(tree(path.join(modularRoot, 'dist', 'sample-esm-view')))
.toMatchInlineSnapshot(`
"sample-esm-view
├─ index.html #17sfbiz
├─ index.html #1t5wlh8
├─ package.json
└─ static
└─ js
Expand Down Expand Up @@ -290,7 +290,7 @@ describe('modular-scripts', () => {
expect(tree(path.join(modularRoot, 'dist', 'sample-esm-view')))
.toMatchInlineSnapshot(`
"sample-esm-view
├─ index.html #17sfbiz
├─ index.html #1t5wlh8
├─ package.json
└─ static
└─ js
Expand Down Expand Up @@ -327,6 +327,158 @@ describe('modular-scripts', () => {
});
});

describe('WHEN building a esm-view with resolutions', () => {
beforeAll(async () => {
await fs.copyFile(
path.join(__dirname, 'TestViewPackages.test-tsx'),
path.join(packagesPath, targetedView, 'src', 'index.tsx'),
);

const packageJsonPath = path.join(
packagesPath,
targetedView,
'package.json',
);
const packageJson = (await fs.readJSON(
packageJsonPath,
)) as CoreProperties;

await fs.writeJSON(
packageJsonPath,
Object.assign(packageJson, {
dependencies: {
lodash: '^4.17.21',
'lodash.merge': '^4.6.2',
},
}),
);

await execa('yarnpkg', [], {
cwd: modularRoot,
cleanup: true,
});

await modular('build sample-esm-view', {
stdio: 'inherit',
env: {
USE_MODULAR_ESBUILD: 'true',
EXTERNAL_CDN_TEMPLATE: 'https://mycustomcdn.net/[name]@[resolution]',
},
});
});

it('THEN outputs the correct directory structure', () => {
expect(tree(path.join(modularRoot, 'dist', 'sample-esm-view')))
.toMatchInlineSnapshot(`
"sample-esm-view
├─ index.html #1t5wlh8
├─ package.json
└─ static
└─ js
├─ _trampoline.js #1j54e9x
├─ index-IDYQ56WQ.js #1g1vpil
└─ index-IDYQ56WQ.js.map #l9p9hs"
`);
});

it('THEN rewrites the dependencies', async () => {
const baseDir = path.join(
modularRoot,
'dist',
'sample-esm-view',
'static',
'js',
);

const indexFile = (
await fs.readFile(path.join(baseDir, 'index-IDYQ56WQ.js'))
).toString();
expect(
prettier.format(indexFile, {
filepath: 'index-F6YQ237K.js',
}),
).toMatchSnapshot();
expect(indexFile).toContain(`https://mycustomcdn.net/react@1`);
expect(indexFile).toContain(`https://mycustomcdn.net/lodash@4`);
});
});

describe('WHEN building a esm-view with resolutions and webpack', () => {
beforeAll(async () => {
await fs.copyFile(
path.join(__dirname, 'TestViewPackages.test-tsx'),
path.join(packagesPath, targetedView, 'src', 'index.tsx'),
);

const packageJsonPath = path.join(
packagesPath,
targetedView,
'package.json',
);
const packageJson = (await fs.readJSON(
packageJsonPath,
)) as CoreProperties;

await fs.writeJSON(
packageJsonPath,
Object.assign(packageJson, {
dependencies: {
lodash: '^4.17.21',
'lodash.merge': '^4.6.2',
},
}),
);

await execa('yarnpkg', [], {
cwd: modularRoot,
cleanup: true,
});

await modular('build sample-esm-view', {
stdio: 'inherit',
env: {
EXTERNAL_CDN_TEMPLATE: 'https://mycustomcdn.net/[name]@[resolution]',
},
});
});

it('THEN outputs the correct directory structure', () => {
expect(tree(path.join(modularRoot, 'dist', 'sample-esm-view')))
.toMatchInlineSnapshot(`
"sample-esm-view
├─ asset-manifest.json #1pem6dg
├─ index.html #1t5wlh8
├─ package.json
└─ static
└─ js
├─ _trampoline.js #1fc8fjx
├─ main.219bc98b.js #g4nmwx
└─ main.219bc98b.js.map #1cp7wwt"
`);
});

it('THEN rewrites the dependencies', async () => {
const baseDir = path.join(
modularRoot,
'dist',
'sample-esm-view',
'static',
'js',
);

const indexFile = (
await fs.readFile(path.join(baseDir, 'main.219bc98b.js'))
).toString();
expect(
prettier.format(indexFile, {
filepath: 'index-F6YQ237K.js',
}),
).toMatchSnapshot();
expect(indexFile).toContain(`https://mycustomcdn.net/react@1`);
expect(indexFile).toContain(`https://mycustomcdn.net/lodash@4`);
});
});

describe('WHEN building a esm-view specifying a dependency to not being rewritten', () => {
beforeAll(async () => {
await modular('build sample-esm-view', {
Expand All @@ -344,7 +496,7 @@ describe('modular-scripts', () => {
expect(tree(path.join(modularRoot, 'dist', 'sample-esm-view')))
.toMatchInlineSnapshot(`
"sample-esm-view
├─ index.html #17sfbiz
├─ index.html #1t5wlh8
├─ package.json
└─ static
└─ js
Expand Down Expand Up @@ -408,7 +560,7 @@ describe('modular-scripts', () => {
expect(tree(path.join(modularRoot, 'dist', 'sample-esm-view')))
.toMatchInlineSnapshot(`
"sample-esm-view
├─ index.html #17sfbiz
├─ index.html #1t5wlh8
├─ package.json
└─ static
└─ js
Expand Down Expand Up @@ -472,7 +624,7 @@ describe('modular-scripts', () => {
expect(tree(path.join(modularRoot, 'dist', 'sample-esm-view')))
.toMatchInlineSnapshot(`
"sample-esm-view
├─ index.html #17sfbiz
├─ index.html #1t5wlh8
├─ package.json
└─ static
└─ js
Expand Down