-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[LEOP-287]Apply all customize features to CRA5-Part1 #144
Changes from 9 commits
714c699
0aa33ad
cf50cb4
1e895a1
017a2b0
4334991
220a660
f158bd1
d98838d
bea8365
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
Our react scripts fork includes a number of custom configuration items in order to support building web products at Skyscanner. The table below will describe what each of the configs do | ||
|
||
## Features Description | ||
|
||
| Feature | Description | Default Value | | ||
|:---|:--|:---| | ||
| **babelIncludePrefixes** | Array of module name prefixes to opt into babel compilation. <br> Default includes **@skyscanner/bpk-, bpk- and saddlebag-** packages by default to be compiled | **[@skyscanner/bpk-, bpk- and saddlebag-]** | | ||
| **sriEnabled** | Determines if Subresource Intergrity is used during build to add an integrity hash for files. <br> The SRI is a security feature to enable browsers to verify the files they fetch are unmodified. <br> If enabled crossOriginLoading value is overriden with anonymous to allow output to have integrity value <br> See [webpack subresource integrity docs](https://github.com/waysact/webpack-subresource-integrity/blob/master/README.md) | **false** (this is currently the default in the future security may want to make it true by default but pending them still trying things about) | | ||
| **crossOriginLoading** | Option to enable cross origin loading of chunks to modify the default webpack behaviour of being false. <br> Docs: https://webpack.js.org/configuration/output/#outputcrossoriginloading | **false** | | ||
| **ignoreCssWarnings** | Provides the ablity to supress CSS ordering warnings when its safe and ordering is not of a concern on the output <br> See [mini css extract plugin docs](https://github.com/webpack-contrib/mini-css-extract-plugin#remove-order-warnings) | **false** - by default we should care about order as it can sometimes have an output impact | | ||
| **cssModules** | Determines if cssModules are being used. <br> If enabled supports css modules and configures css-loader for use <br> If not enabled supports sass modules in the project and configures sass-loader for use | **true** | | ||
| **amdExludes** | Array of module names to be excluded from AMD ([Asynchronous Module Definition](https://webpack.js.org/api/module-methods/#amd)) parsing.<br> lodash included by defeault. | **['lodash']** | | ||
| **externals** | Provides a way of excluding dependencies from the bundles and instead relies on them being available at runtime on the clients environment E.g. React libraries.<br> See https://webpack.js.org/configuration/externals/ | **{}** | | ||
| **ssrExternals** | The same as above `externals` except used for server side rendering only in **ssr.js** | **{}** | | ||
| **enableAutomaticChunking** | Opts into automatic chunking of vender, common and app code.<br> When enabled the **splitChunks** plugin creates vender and common chunks which are split and when provided uses the `venderChunkRegex` to specify what is in each chunk.<br> When enabled **runtimeChunk** plugin creates a separate runtime chunk for projects to enable long term caching. | **false** | | ||
| **vendorsChunkRegex** | Regex for picking what goes into the vendors chunk. Requires enableAutomaticChunking to be enabled.<br> See [cacheGroups](https://webpack.js.org/plugins/split-chunks-plugin/#splitchunkscachegroups) docs for further details. | | | ||
| **sassFunctions** | This function encodes svg content into `base64` when there is a `bpk-icon` in the.scss file. | | | ||
|
||
## How to add new feature | ||
|
||
- Add the custom feature to backpack-addons. | ||
- Require features in the file(for example, webpack.config.js) where they are needed. | ||
- For each line of code that is changed, make sure to add a comment `// #backpack-addon {{featureName}}` | ||
- Try to keep the lines of code changed outside of the backpack-addons folder to a minimum | ||
`require(...../backpack-addons/...)` files instead of writing it inline as much as possible. | ||
- Add a description of the new feature in the table above the current document. | ||
|
||
## How to upgrade from the upstream `facebook/create-react-app` repo | ||
|
||
- Replace all of `packages/react-scripts` with the upstream version. | ||
- Restore all features in `packages/react-scripts/backpack-addons` folder from the old version of BRS. | ||
- Restore (will require manual work+checking) every line which has a `// #backpack-addons` comment. | ||
- Compare [upgrade] document and restore the rest of the content (for example, added files, other modified files). | ||
- Test for project. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
'use strict'; | ||
|
||
const paths = require('../config/paths'); | ||
const appPackageJson = require(paths.appPackageJson); | ||
const bpkReactScriptsConfig = appPackageJson['backpack-react-scripts'] || {}; | ||
|
||
module.exports = { | ||
test: new RegExp( | ||
`(^|/)(${(bpkReactScriptsConfig.amdExcludes || []) | ||
.concat('lodash') | ||
.join('|')})(/|.|$)` | ||
), | ||
parser: { | ||
amd: false, | ||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
"use strict"; | ||
|
||
const paths = require("../config/paths"); | ||
const appPackageJson = require(paths.appPackageJson); | ||
const bpkReactScriptsConfig = appPackageJson["backpack-react-scripts"] || {}; | ||
const customModuleRegexes = bpkReactScriptsConfig.babelIncludePrefixes | ||
? bpkReactScriptsConfig.babelIncludePrefixes.map( | ||
(prefix) => new RegExp(`node_modules[\\/]${prefix}`) | ||
) | ||
: []; | ||
|
||
// Backpack / saddlebag node module regexes | ||
const backpackModulesRegex = /node_modules[\\/]bpk-/; | ||
const saddlebagModulesRegex = /node_modules[\\/]saddlebag-/; | ||
const scopedBackpackModulesRegex = /node_modules[\\/]@skyscanner[\\/]bpk-/; | ||
|
||
module.exports = () => { | ||
return [ | ||
paths.appSrc, | ||
backpackModulesRegex, | ||
saddlebagModulesRegex, | ||
scopedBackpackModulesRegex, | ||
...customModuleRegexes, | ||
]; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
'use strict'; | ||
|
||
const paths = require("../config/paths"); | ||
const appPackageJson = require(paths.appPackageJson); | ||
const bpkReactScriptsConfig = appPackageJson['backpack-react-scripts'] || {}; | ||
const crossOriginLoading = bpkReactScriptsConfig.crossOriginLoading || false; | ||
const sriEnabled = bpkReactScriptsConfig.sriEnabled || false; | ||
|
||
module.exports = { | ||
crossOriginLoading: sriEnabled ? 'anonymous' : crossOriginLoading | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
'use strict'; | ||
|
||
const postcssNormalize = require('postcss-normalize'); | ||
const paths = require('../config/paths'); | ||
const appPackageJson = require(paths.appPackageJson); | ||
const bpkReactScriptsConfig = appPackageJson['backpack-react-scripts'] || {}; | ||
const cssModulesEnabled = bpkReactScriptsConfig.cssModules !== false; | ||
|
||
// Backpack / saddlebag node module regexes | ||
const backpackModulesRegex = /node_modules[\\/]bpk-/; | ||
const scopedBackpackModulesRegex = /node_modules[\\/]@skyscanner[\\/]bpk-/; | ||
|
||
const getStyleTestRegexes = regexType => { | ||
// style files regexes, the regex values should keep up to date with webpack.config.js | ||
const cssRegex = /\.css$/; | ||
const cssModuleRegex = /\.module\.css$/; | ||
const sassRegex = /\.(scss|sass)$/; | ||
const sassModuleRegex = /\.module\.(scss|sass)$/; | ||
|
||
switch (regexType) { | ||
case 'css': | ||
return { | ||
and: [cssRegex, () => !cssModulesEnabled], | ||
not: [backpackModulesRegex, scopedBackpackModulesRegex], | ||
}; | ||
case 'cssModule': | ||
return [ | ||
cssModuleRegex, | ||
{ | ||
and: [cssRegex, () => cssModulesEnabled], | ||
}, | ||
{ | ||
and: [cssRegex, backpackModulesRegex, scopedBackpackModulesRegex], | ||
}, | ||
]; | ||
case 'sass': | ||
return { | ||
and: [sassRegex, () => !cssModulesEnabled], | ||
not: [backpackModulesRegex, scopedBackpackModulesRegex], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same above. I'm going to change |
||
}; | ||
case 'sassModule': | ||
return [ | ||
sassModuleRegex, | ||
{ | ||
and: [sassRegex, () => cssModulesEnabled], | ||
}, | ||
{ | ||
and: [sassRegex, backpackModulesRegex, scopedBackpackModulesRegex], | ||
}, | ||
]; | ||
default: | ||
throw new Error('Not implemented.'); | ||
} | ||
}; | ||
|
||
const getCSSModuleLocalIdent = () => { | ||
return require('../utils/getCSSModuleLocalIdentWithProjectName')( | ||
appPackageJson.name | ||
); | ||
}; | ||
|
||
module.exports = { | ||
getStyleTestRegexes, | ||
getCSSModuleLocalIdent, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
'use strict'; | ||
|
||
const paths = require('../config/paths'); | ||
const appPackageJson = require(paths.appPackageJson); | ||
const bpkReactScriptsConfig = appPackageJson['backpack-react-scripts'] || {}; | ||
|
||
function externals(isEnvProduction) { | ||
if (!isEnvProduction) { | ||
return { | ||
externals: {}, | ||
} | ||
} | ||
return { | ||
externals: bpkReactScriptsConfig.externals || {}, | ||
} | ||
} | ||
|
||
function ssrExternals() { | ||
return { | ||
externals: bpkReactScriptsConfig.ssrExternals || [], | ||
} | ||
} | ||
|
||
module.exports = { | ||
externals, | ||
ssrExternals | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
'use strict'; | ||
|
||
const paths = require('../config/paths'); | ||
const appPackageJson = require(paths.appPackageJson); | ||
const bpkReactScriptsConfig = appPackageJson['backpack-react-scripts'] || {}; | ||
const ignoreCssWarnings = bpkReactScriptsConfig.ignoreCssWarnings || false; | ||
|
||
module.exports = { | ||
ignoreOrder: ignoreCssWarnings | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
'use strict'; | ||
|
||
const paths = require('../config/paths'); | ||
const appPackageJson = require(paths.appPackageJson); | ||
const bpkReactScriptsConfig = appPackageJson['backpack-react-scripts'] || {}; | ||
|
||
const runtimeChunk = { | ||
runtimeChunk: bpkReactScriptsConfig.enableAutomaticChunking | ||
? { | ||
name: entrypoint => `runtime-${entrypoint.name}`, | ||
} | ||
: false | ||
} | ||
|
||
const ssrRuntimeChunk = { | ||
runtimeChunk: false, | ||
} | ||
|
||
module.exports = { | ||
runtimeChunk, | ||
ssrRuntimeChunk | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
'use strict'; | ||
const sass = require('node-sass'); | ||
|
||
module.exports = { | ||
sassOptions: { | ||
functions: { | ||
'encodebase64($string)': str => { | ||
const buffer = Buffer.from(str.getValue()); | ||
|
||
return sass.types.String(buffer.toString('base64')); | ||
} | ||
} | ||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
'use strict'; | ||
|
||
const paths = require('../config/paths'); | ||
const appPackageJson = require(paths.appPackageJson); | ||
const bpkReactScriptsConfig = appPackageJson['backpack-react-scripts'] || {}; | ||
|
||
module.exports = (isEnvDevelopment) => { | ||
// Automatically split vendor and commons | ||
// https://twitter.com/wSokra/status/969633336732905474 | ||
// https://medium.com/webpack/webpack-4-code-splitting-chunk-graph-and-the-splitchunks-optimization-be739a861366 | ||
return { | ||
splitChunks: bpkReactScriptsConfig.enableAutomaticChunking | ||
? { | ||
chunks: 'all', | ||
name: isEnvDevelopment, | ||
cacheGroups: bpkReactScriptsConfig.vendorsChunkRegex | ||
? { | ||
defaultVendors: { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in webpack5: optimization.splitChunks.cacheGroups.vendors → optimization.splitChunks.cacheGroups.defaultVendors |
||
test: new RegExp(bpkReactScriptsConfig.vendorsChunkRegex) | ||
}, | ||
} | ||
: {}, | ||
} | ||
: {} | ||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
"use strict"; | ||
|
||
const SubresourceIntegrityPlugin = require("webpack-subresource-integrity"); | ||
const paths = require("../config/paths"); | ||
const appPackageJson = require(paths.appPackageJson); | ||
const bpkReactScriptsConfig = appPackageJson["backpack-react-scripts"] || {}; | ||
const sriEnabled = bpkReactScriptsConfig.sriEnabled || false; | ||
|
||
module.exports = () => { | ||
return ( | ||
// Calculate and inject Subresource Integrity (SRI) hashes | ||
// https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity | ||
// This is a security feature that enables browsers to verify that resources | ||
// they fetch (for example, from a CDN) are delivered without unexpected manipulation. | ||
sriEnabled && | ||
new SubresourceIntegrityPlugin({ | ||
enabled: true, | ||
hashFuncNames: ["sha384"], | ||
}) | ||
); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Accroding webpack5 Rule.exclude and Rule.include: If you supply a Rule.exclude option, you cannot also supply a Rule.resource(and, not, or )
So I'm going to change
exclude
here tonot