Skip to content

Commit ca213ab

Browse files
committed
docs: add usage and reasoning to README.md
1 parent 0350e5d commit ca213ab

File tree

1 file changed

+138
-0
lines changed

1 file changed

+138
-0
lines changed

README.md

+138
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,141 @@
11
# scratch-webpack-configuration
22

33
Shared configuration for Scratch's use of webpack
4+
5+
## Usage
6+
7+
Add something like this to your `webpack.config.*js` file:
8+
9+
```javascript
10+
import ScratchWebpackConfigBuilder from 'scratch-webpack-configuration';
11+
12+
const builder = new ScratchWebpackConfigBuilder(
13+
{
14+
rootPath: __dirname,
15+
enableReact: true
16+
})
17+
.setTarget('browserslist')
18+
.addModuleRule({
19+
test: /\.css$/,
20+
use: [/* CSS loaders */]
21+
})
22+
.addPlugin(new CopyWebpackPlugin({
23+
patterns: [/* CopyWebpackPlugin patterns */]
24+
});
25+
26+
if (process.env.FOO === 'bar') {
27+
builder.addPlugin(new MyCustomPlugin());
28+
}
29+
30+
module.exports = builder.get();
31+
```
32+
33+
Call `addModuleRule` and `addPlugin` as few or as many times as needed. If you need multiple configurations, you can
34+
use `clone()` to share a base configuration and then add or override settings:
35+
36+
```javascript
37+
const baseConfig = new ScratchWebpackConfigBuilder({rootPath: __dirname, libraryName: 'my-library'})
38+
.addModuleRule({
39+
test: /\.foo$/,
40+
use: [/* FOO loaders */]
41+
});
42+
43+
const config1 = baseConfig.clone()
44+
.setTarget('browserslist')
45+
.merge({/* arbitrary configuration */})
46+
.addPlugin(new MyCustomPlugin('hi'));
47+
48+
const config2 = baseConfig.clone()
49+
.setTarget('node')
50+
.addPlugin(new MyCustomPlugin('hello'));
51+
52+
module.exports = [
53+
config1.get(),
54+
config2.get()
55+
];
56+
```
57+
58+
## What it does
59+
60+
- Sets up a default configuration that is suitable for most Scratch projects
61+
- Use `enableReact` to enable React support
62+
- Target `node` or `browserslist` (more targets will be added as needed)
63+
- Adds `babel-loader` with the `@babel/preset-env` preset
64+
- Adds `@babel/preset-react` if React support is enabled
65+
- Adds target-specific presets for `webpack` 5's `externals` and `externalsPresets` settings
66+
- Target-specific output directory under `dist/`
67+
- `browserslist` builds to `dist/web/`
68+
- `node` builds to `dist/node/`
69+
- Supports merging in arbitrary configuration with `merge({...})`
70+
71+
## API
72+
73+
### `new ScratchWebpackConfigBuilder(options)`
74+
75+
Creates a new `ScratchWebpackConfigBuilder` instance.
76+
77+
#### `options`
78+
79+
Required:
80+
81+
- `rootPath` (string, required): The root path of the project. This is used to establish defaults for other paths.
82+
83+
Optional:
84+
85+
- `distPath` (string, default: `path.join(rootPath, 'dist')`): The path to the output directory. Defaults to `dist`
86+
- `enableReact` (boolean, default: `false`): Whether to enable React support. Adds `.jsx` to the list of extensions
87+
to process, and adjusts Babel settings.
88+
- `libraryName` (string, default: `undefined`): If set, configures a default entry point and output library name.
89+
under the root path.
90+
- `srcPath` (string, default: `path.join(rootPath, 'src')`): The path to the source directory. Defaults to `src`
91+
under the root path.
92+
93+
## Recommended Configuration
94+
95+
### Package exports
96+
97+
_The `exports` field in `package.json`_
98+
99+
Most `project.json` files specify a `main` entry point, and some specify `browser` as well. Newer versions of Node
100+
support the `exports` field as well. If both are present, `exports` will take precedence.
101+
102+
For more information about `exports`, see: <https://webpack.js.org/guides/package-exports/>, especially the "Target
103+
environment" section.
104+
105+
Unfortunately, plenty of tools don't support `exports` yet, and some that do exhibit some surprising quirks.
106+
107+
Here's what I currently recommend for a project with only one entry point:
108+
109+
```json
110+
{
111+
"main": "./dist/node/foo.js",
112+
"browser": "./dist/web/foo.js",
113+
"exports": {
114+
"webpack": "./src/index.js",
115+
"browser": "./dist/web/foo.js",
116+
"node": "./dist/node/foo.js",
117+
"default": "./src/index.js"
118+
},
119+
}
120+
```
121+
122+
- `main` supports older Node as well as `jest`
123+
- `browser` is present for completeness; I haven't found it strictly necessary
124+
- `exports.webpack` is the entry point for Webpack
125+
- `webpack` will grab the first item under `exports` matching its conditions, including `browser`, so I recommend
126+
listing `exports.webpack` first in the `exports` object
127+
- this allows (for example) `scratch-gui` to build `scratch-vm` from source rather than using the prebuilt version,
128+
resulting in more optimal output and preventing version conflicts due to bundled dependencies
129+
- `exports.default` makes `eslint` happy
130+
- `exports.browser` and `exports.node` prevent `exports`-aware tools from using `exports.default` for all contexts
131+
132+
Note that using `src/index.js` for the `webpack` and `default` exports means that the NPM package must include `src`.
133+
134+
### `browserslist` target
135+
136+
While it could be handy to include `browserslist` configuration in this package, there are tools other than `webpack`
137+
that should use the same `browserslist` configuration. For that reason, I recommend configuring `browserslist` in
138+
your `package.json` file or in a top-level `.browserslistrc` file.
139+
140+
The Scratch system requirements determine the browsers we should target. That information can be found here:
141+
<https://scratch.mit.edu/faq>

0 commit comments

Comments
 (0)