Skip to content

Commit 210c9cc

Browse files
authored
feat: improve test command, support dotenv files, add postcss (#52)
* fix: support all the icon variants and update index.html * feat: add Roboto typeface to shell * chore: dynamically import AppAdapter to create a separate chunk * fix: target node for tests * fix: remove reference to non-existent manifest.json * feat: improve jest config, support snapshots and watch, add postcss * chore: automatically include app name in browser title * chore: re-add DOCTYPE declaration to index.html * chore: name app bundles (app-adapter is external) * chore: delete unused manifest.json
1 parent 87f4803 commit 210c9cc

27 files changed

+3851
-258
lines changed

cli/config/babel.config.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
1-
const browsersList = require('./.browserlistrc')
1+
const browserTargets = require('./.browserlistrc')
2+
const jestTargets = { node: 'current' }
3+
4+
const isTest = process.env.NODE_ENV === 'test'
5+
const targets = isTest ? jestTargets : browserTargets
26

37
module.exports = {
48
presets: [
59
require('@babel/preset-react'),
610
require('@babel/preset-typescript'),
711
[
812
require('@babel/preset-env'),
9-
{ modules: 'auto', targets: browsersList },
13+
{
14+
modules: 'auto',
15+
targets,
16+
},
1017
],
1118
],
1219
plugins: [

cli/config/jest.config.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
module.exports = {
22
verbose: true,
3-
transform: JSON.stringify({
3+
transform: {
44
'^.+\\.[t|j]sx?$': require.resolve('./jest.transform.js'),
5-
}),
5+
},
6+
moduleNameMapper: {
7+
'^.+\\.(css|less)$': require.resolve('./jest.identity.mock.js'),
8+
},
69
}

cli/config/jest.identity.mock.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = {}

cli/config/rollup.config.js

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ const resolve = require('rollup-plugin-node-resolve')
66
const babel = require('rollup-plugin-babel')
77
const commonjs = require('rollup-plugin-commonjs')
88
const json = require('rollup-plugin-json')
9+
const postcss = require('rollup-plugin-postcss')
10+
const replace = require('rollup-plugin-replace')
11+
const visualize = require('rollup-plugin-visualizer')
912

1013
const { reporter } = require('@dhis2/cli-helpers-engine')
1114

@@ -31,7 +34,9 @@ const bundle = ({
3134
Object.keys({
3235
...standardLibs,
3336
...pkg.peerDependencies,
34-
}).join('|')
37+
})
38+
.map(name => `^${name}(/.+)?$`)
39+
.join('|')
3540
)
3641

3742
const sourcemap = mode === 'production' ? true : 'inline'
@@ -52,15 +57,37 @@ const bundle = ({
5257
banner: '/* eslint-disable */',
5358
},
5459
],
55-
external: id => externals.test(id),
60+
external: bundleDeps
61+
? id => externals.test(id)
62+
: id => !/^\.+\//.test(id),
5663
plugins: [
64+
replace({
65+
'process.env.NODE_ENV': `"${mode}"`,
66+
}),
67+
postcss({
68+
autoModules: false,
69+
}),
5770
json(),
58-
resolve({ mainFields: ['module', 'main'] }),
59-
commonjs({ include: /node_modules/ }),
6071
babel({
6172
configFile: require.resolve('./babel.config.js'),
6273
exclude: /node_modules/, // only transpile our source code
6374
}),
75+
resolve({
76+
/*
77+
* TODO: Use of named exports (particularly `react-is` from `react-redux`)
78+
* means we can't actually use `module` entrypoints... We could also explicitly
79+
* add the CJS named exports to the `commonjs` options below, but that requires
80+
* fore-knowledge of all the libraries an app/lib could depend on.
81+
* See https://github.com/rollup/rollup-plugin-commonjs/issues/211#issuecomment-337897124
82+
*/
83+
mainFields: ['main'],
84+
}),
85+
commonjs({ include: /node_modules/ }),
86+
visualize({
87+
filename: path.join(outDir, 'stats.html'),
88+
title: 'DHIS2 Build Analysis',
89+
template: 'treemap',
90+
}),
6491
],
6592
onwarn(warning, warn) {
6693
// skip certain warnings

cli/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
"babel-jest": "^24.9.0",
3131
"chalk": "^2.4.2",
3232
"classnames": "^2.2.6",
33+
"dotenv": "^8.1.0",
34+
"dotenv-expand": "^5.1.0",
3335
"fs-extra": "^8.1.0",
3436
"gaze": "^1.1.3",
3537
"handlebars": "^4.2.1",
@@ -47,6 +49,9 @@
4749
"rollup-plugin-commonjs": "^10.1.0",
4850
"rollup-plugin-json": "^4.0.0",
4951
"rollup-plugin-node-resolve": "^5.0.1",
52+
"rollup-plugin-postcss": "^2.0.3",
53+
"rollup-plugin-replace": "^2.2.0",
54+
"rollup-plugin-visualizer": "^2.6.0",
5055
"styled-jsx": "^3.2.2"
5156
},
5257
"bin": {

cli/src/commands/build.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const parseConfig = require('../lib/parseConfig')
1212
const exitOnCatch = require('../lib/exitOnCatch')
1313
const generateManifest = require('../lib/generateManifest')
1414
const bundleApp = require('../lib/bundleApp')
15+
const loadEnvFiles = require('../lib/loadEnvFiles')
1516

1617
const buildModes = ['development', 'production']
1718

@@ -42,10 +43,12 @@ const handler = async ({
4243
shell: shellSource,
4344
force,
4445
}) => {
46+
const paths = makePaths(cwd)
47+
4548
mode = mode || (dev && 'development') || getNodeEnv() || 'production'
49+
loadEnvFiles(paths, mode)
4650

4751
reporter.info(`Build mode: ${chalk.bold(mode)}`)
48-
const paths = makePaths(cwd)
4952
const config = parseConfig(paths)
5053
const shell = makeShell({ config, paths })
5154

cli/src/commands/start.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,15 @@ const makePaths = require('../lib/paths')
77
const makeShell = require('../lib/shell')
88
const parseConfig = require('../lib/parseConfig')
99
const exitOnCatch = require('../lib/exitOnCatch')
10+
const loadEnvFiles = require('../lib/loadEnvFiles')
1011
const { getShellPort } = require('../lib/shell/env')
1112

1213
const handler = async ({ cwd, force, shell: shellSource }) => {
1314
const paths = makePaths(cwd)
15+
16+
const mode = 'development'
17+
loadEnvFiles(paths, mode)
18+
1419
const config = parseConfig(paths)
1520
const shell = makeShell({ config, paths })
1621

@@ -39,7 +44,7 @@ const handler = async ({ cwd, force, shell: shellSource }) => {
3944
reporter.info(`Building app ${chalk.bold(config.name)}...`)
4045
await compile({
4146
config,
42-
mode: 'development',
47+
mode,
4348
paths,
4449
watch: true,
4550
})

cli/src/commands/test.js

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,27 @@
11
const { reporter } = require('@dhis2/cli-helpers-engine')
22

33
const fs = require('fs-extra')
4-
const path = require('path')
54

65
const makePaths = require('../lib/paths')
7-
const parseConfig = require('../lib/parseConfig')
86
const exitOnCatch = require('../lib/exitOnCatch')
7+
const loadEnvFiles = require('../lib/loadEnvFiles')
98

109
const { runCLI } = require('jest-cli')
1110

12-
const handler = async ({ cwd, force, shell: shellSource }) => {
13-
process.env.BABEL_ENV = 'test'
14-
process.env.NODE_ENV = 'test'
15-
11+
const handler = async ({
12+
verbose,
13+
cwd,
14+
testRegex,
15+
update,
16+
coverage,
17+
watch,
18+
watchAll,
19+
}) => {
1620
const paths = makePaths(cwd)
1721

22+
const mode = (process.env.NODE_ENV = process.env.BABEL_ENV = 'test')
23+
loadEnvFiles(paths, mode)
24+
1825
reporter.info('Running tests...')
1926

2027
await exitOnCatch(
@@ -23,14 +30,32 @@ const handler = async ({ cwd, force, shell: shellSource }) => {
2330
const appJestConfig = fs.existsSync(paths.jestConfig)
2431
? require(paths.jestConfig)
2532
: {}
33+
const pkgJestConfig = require(paths.package).jest
2634

2735
const jestConfig = {
2836
roots: ['./src'],
2937
...defaultJestConfig,
3038
...appJestConfig,
39+
...pkgJestConfig,
3140
}
3241

33-
const result = await runCLI(jestConfig, [paths.base])
42+
reporter.debug('Resolved jest config', jestConfig)
43+
44+
const ci = process.env.CI
45+
46+
const result = await runCLI(
47+
{
48+
testPathPattern: testRegex,
49+
config: JSON.stringify(jestConfig),
50+
updateSnapshot: !ci && update,
51+
collectCoverage: coverage,
52+
watch: (!ci && watch) || undefined,
53+
watchAll: (!ci && watchAll) || undefined,
54+
ci,
55+
verbose: verbose,
56+
},
57+
[paths.base]
58+
)
3459

3560
if (result.results.success) {
3661
reporter.info(`Tests completed`)
@@ -48,9 +73,33 @@ const handler = async ({ cwd, force, shell: shellSource }) => {
4873
}
4974

5075
const command = {
51-
command: 'test',
76+
command: 'test [testRegex]',
5277
aliases: 't',
5378
desc: 'Run application unit tests',
79+
builder: {
80+
updateSnapshot: {
81+
type: 'boolean',
82+
desc: 'Update jest snapshots',
83+
aliases: 'u',
84+
default: false,
85+
},
86+
coverage: {
87+
type: 'boolean',
88+
desc: 'Collect test coverage',
89+
default: false,
90+
},
91+
watch: {
92+
type: 'boolean',
93+
desc: 'Watch modified source files for changes',
94+
alias: 'w',
95+
default: false,
96+
},
97+
watchAll: {
98+
type: 'boolean',
99+
desc: 'Watch all source files for changes',
100+
default: false,
101+
},
102+
},
54103
handler,
55104
}
56105

cli/src/lib/loadEnvFiles.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const fs = require('fs')
2+
const dotenvExpand = require('dotenv-expand')
3+
const dotenv = require('dotenv')
4+
5+
const { reporter } = require('@dhis2/cli-helpers-engine')
6+
7+
module.exports = (paths, NODE_ENV) => {
8+
/*
9+
* Heavily inspired by create-react-app
10+
* https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/config/env.js
11+
*/
12+
13+
const dotenvFiles = [
14+
NODE_ENV && `${paths.dotenv}.${NODE_ENV}.local`,
15+
NODE_ENV && `${paths.dotenv}.${NODE_ENV}`,
16+
NODE_ENV !== 'test' && `${paths.dotenv}.local`,
17+
paths.dotenv,
18+
]
19+
20+
dotenvFiles
21+
.filter(Boolean)
22+
.filter(fs.existsSync)
23+
.forEach(dotenvFile => {
24+
dotenvExpand(
25+
dotenv.config({
26+
path: dotenvFile,
27+
})
28+
)
29+
})
30+
31+
reporter.debug('ENV', process.env)
32+
}

cli/src/lib/paths.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ module.exports = makePaths = (cwd = process.cwd()) => {
2121

2222
base,
2323
package: path.join(base, './package.json'),
24+
dotenv: path.join(base, './.env'),
2425
config: path.join(base, './d2.config.js'),
2526
src: path.join(base, './src'),
2627
appEntry: path.join(base, './src/App.js'),

0 commit comments

Comments
 (0)