Skip to content

Commit f5af141

Browse files
committed
feat: add monorepo compatibility
BREAKING CHANGE: upgraded Pika dependencies. Was going to do this as a separate step, but realized I don't want to maintain an old version
1 parent 286d9e9 commit f5af141

File tree

8 files changed

+1913
-1067
lines changed

8 files changed

+1913
-1067
lines changed

README.md

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ For more details on setting up Pack, refer to the [@pika/pack repository](https:
4444
Add a fixed prefix to every file in the ZIP archive. By default, the zip contains exactly what would be installed into the `node_modules` directory -- phrased another way, if you unzipped an archive generated with the default settings, you would create one folder in your working directory for each of your package's dependencies.
4545

4646
> Listing your archive would look something like this:
47+
>
4748
> ```
4849
> $ unzip -Z1 pkg/dist-dependencies.zip
4950
> express/package.json
@@ -62,15 +63,19 @@ Use the `prefix` option to package all dependencies into a set of nested folders
6263
"pipeline": [
6364
["@pika/plugin-standard-pkg"],
6465
["@pika/plugin-build-node"],
65-
["@ryaninvents/plugin-bundle-dependencies", {
66-
"prefix": "nodejs/node_modules"
67-
}]
66+
[
67+
"@ryaninvents/plugin-bundle-dependencies",
68+
{
69+
"prefix": "nodejs/node_modules"
70+
}
71+
]
6872
]
6973
}
7074
}
7175
```
7276
7377
> Listing your archive would look something like this:
78+
>
7479
> ```
7580
> $ unzip -Z1 pkg/dist-dependencies.zip
7681
> nodejs/node_modules/express/package.json
@@ -81,8 +86,40 @@ Use the `prefix` option to package all dependencies into a set of nested folders
8186
> # ... etc.
8287
> ```
8388
89+
### `packageOverrides`
90+
91+
Override versions for some packages during the install step.
92+
93+
This plugin requires `file:` version specifications for any local packages, conflicting with Yarn's [expectation of version numbers for local packages](https://classic.yarnpkg.com/en/docs/workspaces/#toc-how-to-use-it). Using `packageOverrides` allows this plugin to handle this situation correctly without trying to re-implement any of Yarn's functionality.
94+
95+
Expects an object where the keys are package names and the values are override versions. The same lookup is used for both `dependencies` and `devDependencies`.
96+
97+
```json
98+
{
99+
"dependencies": {
100+
"my-local-package": "0.0.0-semantically-released"
101+
},
102+
"@pika/pack": {
103+
"pipeline": [
104+
["@pika/plugin-standard-pkg"],
105+
["@pika/plugin-build-node"],
106+
[
107+
"@ryaninvents/plugin-bundle-dependencies",
108+
{
109+
"packageOverrides": {
110+
"my-local-package": "file:../my-local-package"
111+
}
112+
}
113+
]
114+
]
115+
}
116+
}
117+
```
118+
84119
## Contributing
120+
85121
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
86122

87123
## License
88-
[MIT](https://choosealicense.com/licenses/mit/)
124+
125+
[MIT](https://choosealicense.com/licenses/mit/)

package.json

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
"main": "index.js",
77
"license": "MIT",
88
"dependencies": {
9-
"@pika/types": "^0.3.1",
10-
"del": "^3.0.0",
9+
"@pika/types": "^0.9.2",
10+
"del": "^5.1.0",
1111
"execa": "^1.0.0",
1212
"fs-extra": "^7.0.1",
1313
"gulp": "^4.0.0",
@@ -36,9 +36,9 @@
3636
},
3737
"devDependencies": {
3838
"@babel/preset-env": "^7.3.1",
39-
"@pika/pack": "^0.3.1",
40-
"@pika/plugin-build-node": "^0.3.10",
41-
"@pika/plugin-standard-pkg": "^0.3.10",
39+
"@pika/pack": "^0.5.0",
40+
"@pika/plugin-build-node": "^0.9.2",
41+
"@pika/plugin-standard-pkg": "^0.9.2",
4242
"@semantic-release/changelog": "^3.0.2",
4343
"@semantic-release/commit-analyzer": "^6.1.0",
4444
"@semantic-release/git": "^7.0.8",
@@ -47,16 +47,17 @@
4747
"@semantic-release/release-notes-generator": "^7.1.4",
4848
"@types/gulp": "^4.0.5",
4949
"@types/gulp-zip": "^4.0.0",
50-
"@types/node": "^10.12.24",
50+
"@types/node": "^13.9.8",
5151
"eslint": "^5.13.0",
5252
"eslint-config-semistandard": "^13.0.0",
5353
"eslint-config-standard": "^12.0.0",
5454
"eslint-plugin-import": "^2.16.0",
5555
"eslint-plugin-node": "^8.0.1",
5656
"eslint-plugin-promise": "^4.0.1",
5757
"eslint-plugin-standard": "^4.0.0",
58-
"jest": "^24.1.0",
58+
"jest": "^25.2.4",
5959
"ls-archive": "^1.3.1",
60+
"prettier": "^2.0.2",
6061
"semantic-release": "^15.13.3",
6162
"typescript": "^3.3.3"
6263
},
@@ -138,7 +139,7 @@
138139
},
139140
"scripts": {
140141
"test": "jest",
141-
"build": "pack build",
142+
"build": "pika build",
142143
"semantic-release": "semantic-release"
143144
},
144145
"repository": {

src/__tests__/__snapshots__/index.test.js.snap

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`@ryaninvents/plugin-bundle-dependencies should correctly resolve dependency overrides 1`] = `
4+
Array [
5+
"is-sorted",
6+
"is-sorted/index.js",
7+
"is-sorted/package.json",
8+
"is-sorted/src",
9+
"is-sorted/src/index.js",
10+
]
11+
`;
12+
313
exports[`@ryaninvents/plugin-bundle-dependencies should correctly resolve local dependencies 1`] = `
414
Array [
515
"test-library",

src/__tests__/index.test.js

Lines changed: 81 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,18 @@ const DEFAULT_PKG_JSON = {
1515
build: 'pack build'
1616
},
1717
'@pika/pack': {
18-
'pipeline': [
19-
[
20-
'@pika/plugin-standard-pkg'
21-
],
18+
pipeline: [
19+
['@pika/plugin-standard-pkg'],
2220
[
2321
'@pika/plugin-build-node',
2422
{
25-
'minNodeVersion': '8'
23+
minNodeVersion: '8'
2624
}
2725
],
28-
[
29-
thisPackageName
30-
]
26+
[thisPackageName]
3127
]
3228
},
33-
'devDependencies': {
29+
devDependencies: {
3430
'@pika/pack': '^0.3.1',
3531
'@pika/plugin-build-node': '^0.3.10',
3632
'@pika/plugin-standard-pkg': '^0.3.10',
@@ -41,23 +37,27 @@ const DEFAULT_PKG_JSON = {
4137
describe('@ryaninvents/plugin-bundle-dependencies', () => {
4238
let createdDirs = [];
4339

44-
async function initRepo ({ packageJson: pkg = DEFAULT_PKG_JSON, packageManager = 'npm', stdio } = {}) {
45-
const { filepath: workingDir } = createTempDir(
46-
{ name: 'test-repo-{wwwwdddd}' },
47-
[createTempDir({ name: 'src' }, [
48-
createTempFile({ name: 'index.js', data: '// Hello world' })
49-
])]
50-
);
40+
async function initRepo({
41+
packageJson: pkg = DEFAULT_PKG_JSON,
42+
packageManager = 'npm',
43+
stdio,
44+
skipInstall = false
45+
} = {}) {
46+
const { filepath: workingDir } = createTempDir({ name: 'test-repo-{wwwwdddd}' }, [
47+
createTempDir({ name: 'src' }, [createTempFile({ name: 'index.js', data: '// Hello world' })])
48+
]);
5149
let packageJson = pkg;
5250
if (typeof packageJson === 'function') {
5351
packageJson = packageJson(workingDir);
5452
}
5553
await fs.writeFile(join(workingDir, 'package.json'), JSON.stringify(packageJson, null, 2));
56-
await installDependencies(workingDir, {
57-
cwd: workingDir,
58-
options: { env: { NODE_ENV: 'development' } },
59-
packageManager
60-
});
54+
if (!skipInstall) {
55+
await installDependencies(workingDir, {
56+
cwd: workingDir,
57+
options: { env: { NODE_ENV: 'development' } },
58+
packageManager
59+
});
60+
}
6161
createdDirs.push(workingDir);
6262
return { workingDir };
6363
}
@@ -77,12 +77,9 @@ describe('@ryaninvents/plugin-bundle-dependencies', () => {
7777
},
7878
stdio: 'inherit'
7979
});
80-
expect(async () => fs.access(`${workingDir}/package.json`, fs.constants.F_OK))
81-
.not.toThrow();
82-
expect(async () => fs.access(`${workingDir}/src`, fs.constants.X_OK))
83-
.not.toThrow();
84-
expect(async () => fs.access(`${workingDir}/node_modules`, fs.constants.X_OK))
85-
.not.toThrow();
80+
expect(async () => fs.access(`${workingDir}/package.json`, fs.constants.F_OK)).not.toThrow();
81+
expect(async () => fs.access(`${workingDir}/src`, fs.constants.X_OK)).not.toThrow();
82+
expect(async () => fs.access(`${workingDir}/node_modules`, fs.constants.X_OK)).not.toThrow();
8683
}, 60e3);
8784

8885
it('should correctly resolve local dependencies', async () => {
@@ -95,16 +92,15 @@ describe('@ryaninvents/plugin-bundle-dependencies', () => {
9592
});
9693
await fs.writeFile(`${libProj.workingDir}/index.js`, '// Hello world');
9794
const mainProj = await initRepo({
98-
packageJson: (mainDir) => ({
95+
packageJson: mainDir => ({
9996
...DEFAULT_PKG_JSON,
10097
dependencies: {
10198
'test-library': `file:${relative(mainDir, libProj.workingDir)}`
10299
}
103100
}),
104101
stdio: 'inherit'
105102
});
106-
expect(async () => fs.access(`${mainProj.workingDir}/node_modules/test-library`, fs.constants.X_OK))
107-
.not.toThrow();
103+
expect(async () => fs.access(`${mainProj.workingDir}/node_modules/test-library`, fs.constants.X_OK)).not.toThrow();
108104
const contents = String(await fs.readFile(`${mainProj.workingDir}/node_modules/test-library/index.js`));
109105
expect(contents).toBe('// Hello world');
110106

@@ -121,6 +117,53 @@ describe('@ryaninvents/plugin-bundle-dependencies', () => {
121117
expect(archiveEntries).toMatchSnapshot();
122118
}, 60e3);
123119

120+
it('should correctly resolve dependency overrides', async () => {
121+
const libProj = await initRepo({
122+
packageJson: {
123+
...DEFAULT_PKG_JSON,
124+
name: 'is-sorted'
125+
},
126+
stdio: 'inherit'
127+
});
128+
await fs.writeFile(`${libProj.workingDir}/index.js`, '// Hello world');
129+
const mainProj = await initRepo({
130+
packageJson: mainDir => ({
131+
...DEFAULT_PKG_JSON,
132+
dependencies: {
133+
// Using a real package for testing. This will be installed in the "working directory"
134+
// to simulate a monorepo setup, but will be overridden at pack time.
135+
'is-sorted': '=1.0.5'
136+
},
137+
'@pika/pack': {
138+
pipeline: DEFAULT_PKG_JSON['@pika/pack'].pipeline.map(config => {
139+
if (config[0] !== thisPackageName) return config;
140+
return [
141+
thisPackageName,
142+
{
143+
packageOverrides: {
144+
'is-sorted': `file:${relative(mainDir, libProj.workingDir)}`
145+
}
146+
}
147+
];
148+
})
149+
}
150+
}),
151+
stdio: 'inherit'
152+
});
153+
154+
await execa('npm', ['run', 'build'], {
155+
env: { NODE_ENV: 'production' },
156+
cwd: mainProj.workingDir
157+
});
158+
const archiveEntries = await new Promise((resolve, reject) => {
159+
archive.list(`${mainProj.workingDir}/pkg/dist-dependencies.zip`, (err, results) => {
160+
if (err) return reject(err);
161+
return resolve(results.map(file => file.getPath()).sort());
162+
});
163+
});
164+
expect(archiveEntries).toMatchSnapshot();
165+
}, 60e3);
166+
124167
it('should create a zip file with node_modules', async () => {
125168
const { workingDir } = await initRepo({
126169
packageJson: {
@@ -138,10 +181,8 @@ describe('@ryaninvents/plugin-bundle-dependencies', () => {
138181
env: { NODE_ENV: 'production' },
139182
cwd: workingDir
140183
});
141-
expect(async () => fs.access(`${workingDir}/pkg/package.json`, fs.constants.F_OK))
142-
.not.toThrow();
143-
expect(async () => fs.access(`${workingDir}/pkg/dist-dependencies.zip`, fs.constants.F_OK))
144-
.not.toThrow();
184+
expect(async () => fs.access(`${workingDir}/pkg/package.json`, fs.constants.F_OK)).not.toThrow();
185+
expect(async () => fs.access(`${workingDir}/pkg/dist-dependencies.zip`, fs.constants.F_OK)).not.toThrow();
145186
const archiveEntries = await new Promise((resolve, reject) => {
146187
archive.list(`${workingDir}/pkg/dist-dependencies.zip`, (err, results) => {
147188
if (err) return reject(err);
@@ -202,20 +243,15 @@ describe('@ryaninvents/plugin-bundle-dependencies', () => {
202243
'map-obj': '=4.1.0'
203244
},
204245
'@pika/pack': {
205-
'pipeline': [
206-
[
207-
'@pika/plugin-standard-pkg'
208-
],
246+
pipeline: [
247+
['@pika/plugin-standard-pkg'],
209248
[
210249
'@pika/plugin-build-node',
211250
{
212-
'minNodeVersion': '8'
251+
minNodeVersion: '8'
213252
}
214253
],
215-
[
216-
thisPackageName,
217-
{ prefix: 'nodejs/node_modules' }
218-
]
254+
[thisPackageName, { prefix: 'nodejs/node_modules' }]
219255
]
220256
}
221257
},
@@ -225,10 +261,8 @@ describe('@ryaninvents/plugin-bundle-dependencies', () => {
225261
env: { NODE_ENV: 'production' },
226262
cwd: workingDir
227263
});
228-
expect(async () => fs.access(`${workingDir}/pkg/package.json`, fs.constants.F_OK))
229-
.not.toThrow();
230-
expect(async () => fs.access(`${workingDir}/pkg/dist-dependencies.zip`, fs.constants.F_OK))
231-
.not.toThrow();
264+
expect(async () => fs.access(`${workingDir}/pkg/package.json`, fs.constants.F_OK)).not.toThrow();
265+
expect(async () => fs.access(`${workingDir}/pkg/dist-dependencies.zip`, fs.constants.F_OK)).not.toThrow();
232266
const archiveEntries = await new Promise((resolve, reject) => {
233267
archive.list(`${workingDir}/pkg/dist-dependencies.zip`, (err, results) => {
234268
if (err) return reject(err);

0 commit comments

Comments
 (0)