Skip to content

Commit e2d7111

Browse files
committed
Add template support for any package.json keys (facebook#8082)
1 parent 3f2037b commit e2d7111

File tree

5 files changed

+77
-29
lines changed

5 files changed

+77
-29
lines changed

docusaurus/docs/custom-templates.md

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,18 +58,28 @@ You can add whatever files you want in here, but you must have at least the file
5858

5959
### The `template.json` file
6060

61-
This is where you can define dependencies (only dependencies are supported for now), as well as any custom scripts that your template relies on.
61+
This is the configuration file for your template. It allows you to define information that should become a part of the generated project's `package.json` file, such as dependencies (only dependencies are supported for now) and any custom scripts that your template relies on. It should be structured as follows:
6262

6363
```json
6464
{
65-
"dependencies": {
66-
"serve": "^11.2.0"
67-
},
68-
"scripts": {
69-
"serve": "serve -s build",
70-
"build-and-serve": "npm run build && npm run serve"
65+
"package": {
66+
"dependencies": {
67+
"serve": "^11.2.0"
68+
},
69+
"scripts": {
70+
"serve": "serve -s build",
71+
"build-and-serve": "npm run build && npm run serve"
72+
},
73+
"browserslist": [
74+
"defaults",
75+
"not IE 11",
76+
"not IE_Mob 11",
77+
"maintained node versions",
78+
]
7179
}
7280
}
7381
```
7482

83+
Any values you add for `"dependencies"` and `"scripts"` will be merged with the values used in the initialisation process of `react-scripts`. Any other information you add to `"package"` will be added to the generated project's `package.json` file, replacing any existing values associated with those keys.
84+
7585
For convenience, we always replace `npm run` with `yarn` in your custom `"scripts"`, as well as in your `README` when projects are initialized with yarn.
Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
{
2-
"dependencies": {
3-
"@testing-library/react": "^9.3.2",
4-
"@testing-library/jest-dom": "^4.2.4",
5-
"@testing-library/user-event": "^7.1.2",
6-
"@types/node": "^12.0.0",
7-
"@types/react": "^16.9.0",
8-
"@types/react-dom": "^16.9.0",
9-
"@types/jest": "^24.0.0",
10-
"typescript": "~3.7.2"
2+
"package": {
3+
"dependencies": {
4+
"@testing-library/react": "^9.3.2",
5+
"@testing-library/jest-dom": "^4.2.4",
6+
"@testing-library/user-event": "^7.1.2",
7+
"@types/node": "^12.0.0",
8+
"@types/react": "^16.9.0",
9+
"@types/react-dom": "^16.9.0",
10+
"@types/jest": "^24.0.0",
11+
"typescript": "~3.7.2"
12+
}
1113
}
1214
}

packages/cra-template/template.json

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
{
2-
"dependencies": {
3-
"@testing-library/react": "^9.3.2",
4-
"@testing-library/jest-dom": "^4.2.4",
5-
"@testing-library/user-event": "^7.1.2"
2+
"package": {
3+
"dependencies": {
4+
"@testing-library/react": "^9.3.2",
5+
"@testing-library/jest-dom": "^4.2.4",
6+
"@testing-library/user-event": "^7.1.2"
7+
}
68
}
79
}
Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
{
2-
"dependencies": {
3-
"bootstrap": "4.3.1",
4-
"jest": "24.9.0",
5-
"node-sass": "4.12.0",
6-
"normalize.css": "7.0.0",
7-
"prop-types": "15.7.2",
8-
"test-integrity": "2.0.1"
2+
"package": {
3+
"dependencies": {
4+
"bootstrap": "4.3.1",
5+
"jest": "24.9.0",
6+
"node-sass": "4.12.0",
7+
"normalize.css": "7.0.0",
8+
"prop-types": "15.7.2",
9+
"test-integrity": "2.0.1"
10+
}
911
}
1012
}

packages/react-scripts/scripts/init.js

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,37 @@ module.exports = function(
118118
templateJson = require(templateJsonPath);
119119
}
120120

121+
const templatePackage = templateJson.package || {};
122+
123+
// Keys to ignore in templatePackage
124+
const templatePackageBlacklist = [
125+
'devDependencies',
126+
'peerDependencies',
127+
'name',
128+
];
129+
130+
// Keys from templatePackage that will be merged with appPackage
131+
const templatePackageToMerge = [
132+
'dependencies',
133+
'scripts',
134+
];
135+
136+
// Keys from templatePackage that will be added to appPackage,
137+
// replacing any existing entries.
138+
const templatePackageToReplace = Object.keys(templatePackage)
139+
.filter(key => {
140+
return (
141+
templatePackageBlacklist.indexOf(key) === -1 &&
142+
templatePackageToMerge.indexOf(key) === -1
143+
);
144+
});
145+
121146
// Copy over some of the devDependencies
122147
appPackage.dependencies = appPackage.dependencies || {};
123148

124149
// Setup the script rules
125-
const templateScripts = templateJson.scripts || {};
150+
// TODO: deprecate 'scripts' key directly on templateJson
151+
const templateScripts = templatePackage.scripts || templateJson.scripts || {};
126152
appPackage.scripts = Object.assign(
127153
{
128154
start: 'react-scripts start',
@@ -152,6 +178,11 @@ module.exports = function(
152178
// Setup the browsers list
153179
appPackage.browserslist = defaultBrowsers;
154180

181+
// Add templatePackage keys/values to appPackage, replacing existing entries
182+
templatePackageToReplace.forEach(key => {
183+
appPackage[key] = templatePackage[key];
184+
});
185+
155186
fs.writeFileSync(
156187
path.join(appPath, 'package.json'),
157188
JSON.stringify(appPackage, null, 2) + os.EOL
@@ -221,7 +252,8 @@ module.exports = function(
221252
}
222253

223254
// Install additional template dependencies, if present
224-
const templateDependencies = templateJson.dependencies;
255+
// TODO: deprecate 'dependencies' key directly on templateJson
256+
const templateDependencies = templatePackage.dependencies || templateJson.dependencies;
225257
if (templateDependencies) {
226258
args = args.concat(
227259
Object.keys(templateDependencies).map(key => {

0 commit comments

Comments
 (0)