Skip to content

Commit

Permalink
feat: Add ability to override configuration (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
reintroducing authored Aug 17, 2019
1 parent 974e1a9 commit ac1550e
Show file tree
Hide file tree
Showing 17 changed files with 430 additions and 309 deletions.
12 changes: 11 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
{
"extends": "@spothero"
"extends": [
"@spothero",
"plugin:prettier/recommended",
"prettier/babel",
"prettier/react"
],
"rules": {
"prettier/prettier": "error",
"@spothero/spothero/ternary-parentheses": 0,
"no-console": 0
}
}
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.md
21 changes: 21 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"bracketSpacing": false,
"endOfLine": "lf",
"singleQuote": true,
"tabWidth": 4,
"trailingComma": "es5",
"overrides": [
{
"files": "*.json",
"options": {
"tabWidth": 2
}
},
{
"files": "*.scss",
"options": {
"singleQuote": false
}
}
]
}
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,41 @@ Follow the steps below to install and initialize rSR in a new project.
```bash
npm start
```

## Available Configuration
You can override a handful of configuration options by creating a `rsr.config.js` file at the root of your project. Most options are direct pass throughs of their webpack counterparts as shown below. The module should export a function that returns an object. The following parameters are passed into the function:

* `webpack`: The internal rSR webpack instance.
* `mode`: The environment in which the config will be executed.
* `defaultConfig`: The default configuration for the given mode.
* While you can use this to override every option in rSR, it is not recommended. This is mostly provided as an escape hatch or if you need to pull existing values from the config and should be used sparingly. **Destructuring this onto the return object and altering it can cause your builds to not function correctly.**

```js
module.exports = ({webpack, mode, defaultConfig}) => {
const isDev = mode === 'development'; // 'development', 'production'
return {
// config options
};
};
```

You can use the mode passed to set options based on the environment. All options are optional, you can include as little or as many as you'd like.
### devServerPort
The port to run the dev server on.
### devServerProxy
Adds a [proxy middleware](https://webpack.js.org/configuration/dev-server/#devserverproxy) to the dev server.
### optimization
An [optimization](https://webpack.js.org/configuration/optimization/) object to apply. By default, the `minimizer` is already set for production builds (both OptimizeCssAssetsPlugin and TerserPlugin). If you wish to overwrite these you can pass a new one in. Other settings passed here will be applied as is.
### plugins
An array of additional [plugins](https://webpack.js.org/configuration/plugins/#plugins) to apply.
### rules
An array of additional [rules](https://webpack.js.org/configuration/module/#modulerules) to apply.
### sourceMap
The style of [source map](https://webpack.js.org/configuration/devtool/#devtool) to use. Set to false for any mode to disable.
47 changes: 25 additions & 22 deletions bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,34 @@ const chalk = require('chalk');
const spawn = require('cross-spawn');

function runScript(script) {
spawn.sync(
'node',
[require.resolve(`../scripts/${script}`)],
{stdio: 'inherit'}
);
spawn.sync('node', [require.resolve(`../scripts/${script}`)], {
stdio: 'inherit',
});
}

function determineScript(script) {
if (script) {
switch (script) {
case 'start':
case 'build':
case 'contrib':
runScript(script);
break;

default:
console.log(chalk.red(`The script ${script} does not exist.`));
break;
}
} else {
// rsr ran with no params, initialize a project
runScript('init');
}
}

const args = arg({
'--event': String, // rsr --event=start
'-e': '--event', // rsr -e start
'--event': String, // rsr --event=start
'-e': '--event', // rsr -e start
});
const script = args['--event'];

if (script) {
switch (script) {
case 'start':
case 'build':
runScript(script);
break;

default:
console.log(chalk.red(`The script ${script} does not exist.`));
break;
}
} else {
// rsr ran with no params, initialize a project
runScript('init');
}
determineScript(script);
75 changes: 35 additions & 40 deletions config/webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
const path = require('path');
const del = require('del');
const StyleLintPlugin = require('stylelint-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
.BundleAnalyzerPlugin;
const eslintFriendlyFormatter = require('eslint-friendly-formatter');
const postCssImport = require('postcss-import');
const postcssPresetEnv = require('postcss-preset-env');
const flexbugsFixes = require('postcss-flexbugs-fixes');

module.exports = function(mode = 'development') {
const isDev = (mode === 'development' || mode === 'test');
module.exports = (mode = 'development') => {
const isDev = mode === 'development' || mode === 'test';
const dist = path.resolve(process.cwd(), 'dist');
const src = path.resolve(process.cwd(), 'src');
const entry = [`${src}/index.js`];
Expand All @@ -31,23 +31,17 @@ module.exports = function(mode = 'development') {
entry.unshift('react-hot-loader/patch');
}

del.sync(dist);

return {
mode: (isDev)
? 'development'
: 'production',
mode: isDev ? 'development' : 'production',
target: 'web',
devtool: (isDev)
? 'cheap-module-source-map'
: 'source-map',
devtool: isDev ? 'cheap-module-source-map' : 'source-map',
entry,
output: {
filename: `js/[name]${(isDev) ? '' : '-[hash]'}.js`,
filename: `js/[name]${isDev ? '' : '-[hash]'}.js`,
path: `${dist}`,
...(isDev) && {
...(isDev && {
publicPath: '/',
},
}),
},
plugins: [
new StyleLintPlugin(),
Expand All @@ -56,31 +50,24 @@ module.exports = function(mode = 'development') {
template: `${src}/index.html`,
}),
new MiniCssExtractPlugin({
filename: `css/[name]${(isDev) ? '' : '-[hash]'}.css`,
chunkFilename: (isDev)
filename: `css/[name]${isDev ? '' : '-[hash]'}.css`,
chunkFilename: isDev
? 'css/[name]-[id].css'
: 'css/[name]-[contenthash].css',
}),
new BundleAnalyzerPlugin({
analyzerMode: (isDev) ? 'static' : 'disabled',
analyzerMode: isDev ? 'static' : 'disabled',
openAnalyzer: false,
}),
],
resolve: {
alias: {
...(isDev) && {
...(isDev && {
'react-dom': '@hot-loader/react-dom',
},
}),
},
modules: [
'node_modules',
src,
],
extensions: [
'.js',
'.jsx',
'.json',
],
modules: ['node_modules', src],
extensions: ['.js', '.jsx', '.json'],
},
module: {
rules: [
Expand Down Expand Up @@ -115,7 +102,9 @@ module.exports = function(mode = 'development') {
options: {
importLoaders: 2,
modules: {
localIdentName: `[name]-[local]${(isDev) ? '' : '-[hash:base64]'}`,
localIdentName: `[name]-[local]${
isDev ? '' : '-[hash:base64]'
}`,
},
sourceMap: isDev,
},
Expand Down Expand Up @@ -150,7 +139,9 @@ module.exports = function(mode = 'development') {
{
loader: 'file-loader',
options: {
name: `[folder]/[name]${(isDev) ? '' : '-[contenthash]'}.[ext]`,
name: `[folder]/[name]${
isDev ? '' : '-[contenthash]'
}.[ext]`,
outputPath: 'img',
},
},
Expand All @@ -165,29 +156,33 @@ module.exports = function(mode = 'development') {
],
},
stats,
...(isDev) && {
...(isDev && {
devServer: {
historyApiFallback: true,
hot: true,
open: true,
port: 3000,
publicPath: '/',
stats,
writeToDisk: true,
},
},
}),
performance: {
hints: false,
},
optimization: {
...(!isDev) && {
...(!isDev && {
minimizer: [
new OptimizeCssAssetsPlugin({
cssProcessorPluginOptions: {
preset: ['default', {
discardComments: {
removeAll: true,
preset: [
'default',
{
discardComments: {
removeAll: true,
},
},
}],
],
},
}),
new TerserPlugin({
Expand All @@ -203,7 +198,7 @@ module.exports = function(mode = 'development') {
},
}),
],
},
}),
},
};
}
};
Loading

0 comments on commit ac1550e

Please sign in to comment.