Skip to content

Commit

Permalink
Add template support for any package.json keys (#8082)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomvalorsa committed Dec 22, 2019
1 parent 3f2037b commit e2d7111
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 29 deletions.
24 changes: 17 additions & 7 deletions docusaurus/docs/custom-templates.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,28 @@ You can add whatever files you want in here, but you must have at least the file

### The `template.json` file

This is where you can define dependencies (only dependencies are supported for now), as well as any custom scripts that your template relies on.
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:

```json
{
"dependencies": {
"serve": "^11.2.0"
},
"scripts": {
"serve": "serve -s build",
"build-and-serve": "npm run build && npm run serve"
"package": {
"dependencies": {
"serve": "^11.2.0"
},
"scripts": {
"serve": "serve -s build",
"build-and-serve": "npm run build && npm run serve"
},
"browserslist": [
"defaults",
"not IE 11",
"not IE_Mob 11",
"maintained node versions",
]
}
}
```

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.

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.
20 changes: 11 additions & 9 deletions packages/cra-template-typescript/template.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
{
"dependencies": {
"@testing-library/react": "^9.3.2",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/user-event": "^7.1.2",
"@types/node": "^12.0.0",
"@types/react": "^16.9.0",
"@types/react-dom": "^16.9.0",
"@types/jest": "^24.0.0",
"typescript": "~3.7.2"
"package": {
"dependencies": {
"@testing-library/react": "^9.3.2",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/user-event": "^7.1.2",
"@types/node": "^12.0.0",
"@types/react": "^16.9.0",
"@types/react-dom": "^16.9.0",
"@types/jest": "^24.0.0",
"typescript": "~3.7.2"
}
}
}
10 changes: 6 additions & 4 deletions packages/cra-template/template.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
{
"dependencies": {
"@testing-library/react": "^9.3.2",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/user-event": "^7.1.2"
"package": {
"dependencies": {
"@testing-library/react": "^9.3.2",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/user-event": "^7.1.2"
}
}
}
16 changes: 9 additions & 7 deletions packages/react-scripts/fixtures/kitchensink/template.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
{
"dependencies": {
"bootstrap": "4.3.1",
"jest": "24.9.0",
"node-sass": "4.12.0",
"normalize.css": "7.0.0",
"prop-types": "15.7.2",
"test-integrity": "2.0.1"
"package": {
"dependencies": {
"bootstrap": "4.3.1",
"jest": "24.9.0",
"node-sass": "4.12.0",
"normalize.css": "7.0.0",
"prop-types": "15.7.2",
"test-integrity": "2.0.1"
}
}
}
36 changes: 34 additions & 2 deletions packages/react-scripts/scripts/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,37 @@ module.exports = function(
templateJson = require(templateJsonPath);
}

const templatePackage = templateJson.package || {};

// Keys to ignore in templatePackage
const templatePackageBlacklist = [
'devDependencies',
'peerDependencies',
'name',
];

// Keys from templatePackage that will be merged with appPackage
const templatePackageToMerge = [
'dependencies',
'scripts',
];

// Keys from templatePackage that will be added to appPackage,
// replacing any existing entries.
const templatePackageToReplace = Object.keys(templatePackage)
.filter(key => {
return (
templatePackageBlacklist.indexOf(key) === -1 &&
templatePackageToMerge.indexOf(key) === -1
);
});

// Copy over some of the devDependencies
appPackage.dependencies = appPackage.dependencies || {};

// Setup the script rules
const templateScripts = templateJson.scripts || {};
// TODO: deprecate 'scripts' key directly on templateJson
const templateScripts = templatePackage.scripts || templateJson.scripts || {};
appPackage.scripts = Object.assign(
{
start: 'react-scripts start',
Expand Down Expand Up @@ -152,6 +178,11 @@ module.exports = function(
// Setup the browsers list
appPackage.browserslist = defaultBrowsers;

// Add templatePackage keys/values to appPackage, replacing existing entries
templatePackageToReplace.forEach(key => {
appPackage[key] = templatePackage[key];
});

fs.writeFileSync(
path.join(appPath, 'package.json'),
JSON.stringify(appPackage, null, 2) + os.EOL
Expand Down Expand Up @@ -221,7 +252,8 @@ module.exports = function(
}

// Install additional template dependencies, if present
const templateDependencies = templateJson.dependencies;
// TODO: deprecate 'dependencies' key directly on templateJson
const templateDependencies = templatePackage.dependencies || templateJson.dependencies;
if (templateDependencies) {
args = args.concat(
Object.keys(templateDependencies).map(key => {
Expand Down

0 comments on commit e2d7111

Please sign in to comment.