Skip to content

Commit 59cd57f

Browse files
committed
Add devCheck to localpack
1 parent 7f97929 commit 59cd57f

File tree

6 files changed

+117
-0
lines changed

6 files changed

+117
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
'use strict'
2+
3+
module.exports = {
4+
...require('./main'),
5+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
'use strict'
2+
3+
const { mkdir, readFileSync, writeFile } = require('fs')
4+
const { promisify } = require('util')
5+
6+
const { addScopeDirs } = require('./scope')
7+
8+
const TEMPLATE = readFileSync(`${__dirname}/template.js`, { encoding: 'utf-8' })
9+
10+
const pMkdir = promisify(mkdir)
11+
const pWriteFile = promisify(writeFile)
12+
13+
// Add `{output}/node_modules/{file}.js` for each devDependency.
14+
// The file simply throws an error.
15+
// The goal is to check that the published module does not use devDependencies.
16+
// Without create dummy `node_modules`, it would require `packageRoot`
17+
// devDependencies, which are probably installed since they are needed for
18+
// testing itself.
19+
const addDevChecks = async function({ output }) {
20+
const nodeModules = await getNodeModules({ output })
21+
22+
const devDependencies = getDevDependencies({ output })
23+
24+
await addScopeDirs({ devDependencies, nodeModules })
25+
26+
await Promise.all(
27+
devDependencies.map(name => addDevCheck({ name, nodeModules })),
28+
)
29+
}
30+
31+
// Retrieve `{output}/node_modules`
32+
const getNodeModules = async function({ output }) {
33+
const nodeModules = `${output}/node_modules`
34+
35+
await pMkdir(nodeModules)
36+
37+
return nodeModules
38+
}
39+
40+
// Retrieve all `devDependencies` names.
41+
const getDevDependencies = function({ output }) {
42+
// eslint-disable-next-line import/no-dynamic-require
43+
const { devDependencies = {} } = require(`${output}/package.json`)
44+
const devDependenciesA = Object.keys(devDependencies)
45+
return devDependenciesA
46+
}
47+
48+
// Add the dependency file, based on a simple template file.
49+
const addDevCheck = async function({ name, nodeModules }) {
50+
const devCheckFile = `${nodeModules}/${name}.js`
51+
const content = TEMPLATE.replace(TEMPLATE_TOKEN, name)
52+
await pWriteFile(devCheckFile, content, { encoding: 'utf-8' })
53+
}
54+
55+
const TEMPLATE_TOKEN = 'DEPENDENCY'
56+
57+
module.exports = {
58+
addDevChecks,
59+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
'use strict'
2+
3+
const { mkdir } = require('fs')
4+
const { promisify } = require('util')
5+
6+
const { uniq } = require('../utils')
7+
8+
const pMkdir = promisify(mkdir)
9+
10+
// Package with a scope (`@scope/name`) should be installed within `@scope`,
11+
// which we must create
12+
const addScopeDirs = async function({ devDependencies, nodeModules }) {
13+
const scopeDirs = getScopeDirs({ devDependencies })
14+
15+
await Promise.all(
16+
scopeDirs.map(scopeDir => pMkdir(`${nodeModules}/${scopeDir}`)),
17+
)
18+
}
19+
20+
// Retrieve all scopes
21+
const getScopeDirs = function({ devDependencies }) {
22+
const scopes = devDependencies.filter(hasScope).map(getScope)
23+
const scopesA = uniq(scopes)
24+
return scopesA
25+
}
26+
27+
const hasScope = function(name) {
28+
return name.includes('/')
29+
}
30+
31+
const getScope = function(name) {
32+
return name.split('/')[0]
33+
}
34+
35+
module.exports = {
36+
addScopeDirs,
37+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
'use strict'
2+
3+
throw new Error("Cannot require 'DEPENDENCY' because it is a devDependency")

gulp/utils/localpack-code/main.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const pRename = promisify(rename)
1414

1515
const { getPackageRoot } = require('./root')
1616
const { getTempDir, cleanTempDir } = require('./temp')
17+
const { addDevChecks } = require('./dev_checks')
1718

1819
// Runs `npm pack` then unpack it to `opts.output`
1920
const localpack = async function({ output } = {}) {
@@ -26,6 +27,8 @@ const localpack = async function({ output } = {}) {
2627

2728
await unpack({ packageRoot, tempDir, output: outputA })
2829

30+
await addDevChecks({ output: outputA })
31+
2932
await cleanTempDir({ tempDir })
3033
}
3134

gulp/utils/localpack-code/utils.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@ const omitBy = function(object, condition) {
88
return Object.assign({}, ...pairs)
99
}
1010

11+
// Like Lodash uniq()
12+
const uniq = function(arr) {
13+
return arr.filter(isUnique)
14+
}
15+
16+
const isUnique = function(value, index, arr) {
17+
return arr.slice(0, index).every(valueA => value !== valueA)
18+
}
19+
1120
module.exports = {
1221
omitBy,
22+
uniq,
1323
}

0 commit comments

Comments
 (0)