Skip to content

Commit a14a53a

Browse files
committed
refactor: Separate internal concepts of config and env (#1734)
* refactor: Separate internal concepts of config and env * docs: Adding changeset
1 parent fba7fd5 commit a14a53a

File tree

11 files changed

+129
-91
lines changed

11 files changed

+129
-91
lines changed

.changeset/great-dryers-cross.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
'preact-cli': major
3+
---
4+
5+
Reduces the `env` parameter of `preact.config.js` to only contain 3 values: `isProd`, `isWatch`, and `isServer`.
6+
7+
Previously, `env` contained many semi-duplicated values (`production` and `isProd`, etc) as well as values that were unlikely to be of much use to many users (what flags were set, for instance). Because of this, the signal-to-noise ratio was rather low which we didn't like. As such, we reduced `env` down to the most basic environment info: what type of build is `preact-cli` doing and for which environement?
8+
9+
If you customize your Webpack config using a `preact.config.js`, please be aware that you may need to update which values you consume from `env`.

packages/cli/src/commands/build.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ exports.build = async function buildCommand(src, argv) {
88
argv.src = src || argv.src;
99
// add `default:true`s, `--no-*` disables
1010
argv.prerender = toBool(argv.prerender);
11-
argv.production = toBool(argv.production);
1211

1312
let cwd = resolve(argv.cwd);
1413

@@ -23,7 +22,7 @@ exports.build = async function buildCommand(src, argv) {
2322
await promisify(rimraf)(dest);
2423
}
2524

26-
let stats = await runWebpack(argv, false);
25+
let stats = await runWebpack(argv, true);
2726

2827
if (argv.json) {
2928
await runWebpack.writeJsonStats(cwd, stats);

packages/cli/src/commands/watch.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ exports.watch = async function watchCommand(src, argv) {
99
argv.refresh = argv.rhl;
1010
}
1111
argv.src = src || argv.src;
12-
argv.production = false;
1312
if (argv.sw) {
1413
argv.sw = toBool(argv.sw);
1514
}
@@ -33,7 +32,7 @@ exports.watch = async function watchCommand(src, argv) {
3332
}
3433
}
3534

36-
return runWebpack(argv, true);
35+
return runWebpack(argv, false);
3736
};
3837

3938
const determinePort = (exports.determinePort = async function (port) {

packages/cli/src/lib/babel-config.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
const { tryResolveConfig } = require('../util');
22

3-
module.exports = function (env) {
4-
const { babelConfig, cwd, isProd, refresh } = env;
3+
/**
4+
* @param {boolean} isProd
5+
*/
6+
module.exports = function (config, isProd) {
7+
const { babelConfig, cwd, refresh } = config;
58

69
const resolvedConfig =
710
babelConfig &&

packages/cli/src/lib/webpack/render-html-plugin.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@ function read(path) {
1717
return readFileSync(resolve(__dirname, path), 'utf-8');
1818
}
1919

20-
module.exports = async function renderHTMLPlugin(config) {
20+
/**
21+
* @param {import('../../../types').Env} env
22+
*/
23+
module.exports = async function renderHTMLPlugin(config, env) {
2124
const { cwd, dest, src } = config;
25+
2226
const inProjectTemplatePath = resolve(src, 'template.html');
2327
let template = defaultTemplate;
2428
if (existsSync(inProjectTemplatePath)) {
@@ -89,6 +93,7 @@ module.exports = async function renderHTMLPlugin(config) {
8993
inlineCss: config['inline-css'],
9094
preload: config.preload,
9195
config,
96+
env,
9297
preRenderData: values,
9398
CLI_DATA: { preRenderData: { url, ...routeData } },
9499
ssr: config.prerender ? prerender({ cwd, dest, src }, values) : '',

packages/cli/src/lib/webpack/run-webpack.js

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,29 @@ const serverConfig = require('./webpack-server-config');
1010
const transformConfig = require('./transform-config');
1111
const { error, isDir, warn } = require('../../util');
1212

13-
async function devBuild(env) {
14-
let config = await clientConfig(env);
13+
/**
14+
* @param {import('../../../types').Env} env
15+
*/
16+
async function devBuild(config, env) {
17+
const webpackConfig = await clientConfig(config, env);
1518

16-
await transformConfig(env, config);
19+
await transformConfig(webpackConfig, config, env);
1720

18-
let compiler = webpack(config);
21+
let compiler = webpack(webpackConfig);
1922
return new Promise((res, rej) => {
2023
compiler.hooks.beforeCompile.tap('CliDevPlugin', () => {
2124
if (env['clear']) clear(true);
2225
});
2326

2427
compiler.hooks.done.tap('CliDevPlugin', stats => {
25-
let devServer = config.devServer;
28+
let devServer = webpackConfig.devServer;
2629
let protocol = process.env.HTTPS || devServer.https ? 'https' : 'http';
2730
let host = process.env.HOST || devServer.host || 'localhost';
2831
if (host === '0.0.0.0' && process.platform === 'win32') {
2932
host = 'localhost';
3033
}
31-
let serverAddr = `${protocol}://${host}:${bold(env.port)}`;
32-
let localIpAddr = `${protocol}://${ip.address()}:${bold(env.port)}`;
34+
let serverAddr = `${protocol}://${host}:${bold(config.port)}`;
35+
let localIpAddr = `${protocol}://${ip.address()}:${bold(config.port)}`;
3336

3437
if (stats.hasErrors()) {
3538
process.stdout.write(red('Build failed!\n\n'));
@@ -45,26 +48,28 @@ async function devBuild(env) {
4548

4649
compiler.hooks.failed.tap('CliDevPlugin', rej);
4750

48-
let server = new DevServer(config.devServer, compiler);
51+
let server = new DevServer(webpackConfig.devServer, compiler);
4952
server.start();
5053
res(server);
5154
});
5255
}
5356

54-
async function prodBuild(env) {
55-
env = { ...env, isServer: false, dev: !env.production, ssr: false };
56-
let config = await clientConfig(env);
57-
await transformConfig(env, config);
57+
/**
58+
* @param {import('../../../types').Env} env
59+
*/
60+
async function prodBuild(config, env) {
61+
if (config.prerender) {
62+
const serverEnv = { ...env, isServer: true };
5863

59-
if (env.prerender) {
60-
const serverEnv = Object.assign({}, env, { isServer: true, ssr: true });
61-
let ssrConfig = serverConfig(serverEnv);
62-
await transformConfig(serverEnv, ssrConfig);
63-
let serverCompiler = webpack(ssrConfig);
64+
const serverWebpackConfig = serverConfig(config, serverEnv);
65+
await transformConfig(serverWebpackConfig, config, serverEnv);
66+
const serverCompiler = webpack(serverWebpackConfig);
6467
await runCompiler(serverCompiler);
6568
}
6669

67-
let clientCompiler = webpack(config);
70+
const clientWebpackConfig = await clientConfig(config, env);
71+
await transformConfig(clientWebpackConfig, config, env);
72+
const clientCompiler = webpack(clientWebpackConfig);
6873

6974
try {
7075
let stats = await runCompiler(clientCompiler);
@@ -220,20 +225,26 @@ function stripLoaderFromModuleNames(m) {
220225
return m;
221226
}
222227

223-
module.exports = function (env, watch = false) {
224-
env.isProd = env.production; // shorthand
225-
env.isWatch = !!watch; // use HMR?
226-
env.cwd = resolve(env.cwd || process.cwd());
227-
228-
// env.src='src' via `build` default
229-
let src = resolve(env.cwd, env.src);
230-
env.src = isDir(src) ? src : env.cwd;
228+
/**
229+
* @param {boolean} isProd
230+
*/
231+
module.exports = function (argv, isProd) {
232+
const env = {
233+
isProd,
234+
isWatch: !isProd,
235+
isServer: false,
236+
};
237+
const config = argv;
238+
config.cwd = resolve(argv.cwd || process.cwd());
239+
240+
// config.src='src' via `build` default
241+
const src = resolve(config.cwd, argv.src);
242+
config.src = isDir(src) ? src : config.cwd;
231243

232244
// attach sourcing helper
233-
env.source = dir => resolve(env.src, dir);
245+
config.source = dir => resolve(config.src, dir);
234246

235-
// determine build-type to run
236-
return (watch ? devBuild : prodBuild)(env);
247+
return (isProd ? prodBuild : devBuild)(config, env);
237248
};
238249

239250
module.exports.writeJsonStats = writeJsonStats;

packages/cli/src/lib/webpack/transform-config.js

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ const { error, esmImport, tryResolveConfig, warn } = require('../../util');
66
const FILE = 'preact.config';
77
const EXTENSIONS = ['js', 'json'];
88

9-
async function findConfig(env) {
9+
async function findConfig(cwd) {
1010
let idx = 0;
1111
for (idx; idx < EXTENSIONS.length; idx++) {
12-
let config = `${FILE}.${EXTENSIONS[idx]}`;
13-
let path = resolve(env.cwd, config);
12+
let configFile = `${FILE}.${EXTENSIONS[idx]}`;
13+
let path = resolve(cwd, configFile);
1414
try {
1515
await stat(path);
16-
return { configFile: config, isDefault: true };
16+
return { configFile, isDefault: true };
1717
} catch (e) {}
1818
}
1919

@@ -90,17 +90,20 @@ function parseConfig(config) {
9090
return transformers;
9191
}
9292

93-
module.exports = async function (env, webpackConfig) {
93+
/**
94+
* @param {import('../../../types').Env} env
95+
*/
96+
module.exports = async function (webpackConfig, config, env) {
9497
const { configFile, isDefault } =
95-
env.config !== 'preact.config.js'
96-
? { configFile: env.config, isDefault: false }
97-
: await findConfig(env);
98+
config.config !== 'preact.config.js'
99+
? { configFile: config.config, isDefault: false }
100+
: await findConfig(config.cwd);
98101

99102
const cliConfig = tryResolveConfig(
100-
env.cwd,
103+
config.cwd,
101104
configFile,
102105
isDefault,
103-
env.verbose
106+
config.verbose
104107
);
105108

106109
if (!cliConfig) return;
@@ -111,15 +114,15 @@ module.exports = async function (env, webpackConfig) {
111114
} catch (error) {
112115
warn(
113116
`Failed to load preact-cli config file, using default!\n${
114-
env.verbose ? error.stack : error.message
117+
config.verbose ? error.stack : error.message
115118
}`
116119
);
117120
return;
118121
}
119122

120123
const transformers = parseConfig((m && m.default) || m);
121124

122-
const helpers = new WebpackConfigHelpers(env.cwd);
125+
const helpers = new WebpackConfigHelpers(config.cwd);
123126
for (let [transformer, options] of transformers) {
124127
try {
125128
await transformer(webpackConfig, env, helpers, options);

packages/cli/src/lib/webpack/webpack-base-config.js

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,17 @@ function getSassConfiguration(...includePaths) {
5959
}
6060

6161
/**
62+
* @param {import('../../../types').Env} env
6263
* @returns {import('webpack').Configuration}
6364
*/
64-
module.exports = function createBaseConfig(env) {
65-
const { cwd, isProd, src, source } = env;
65+
module.exports = function createBaseConfig(config, env) {
66+
const { cwd, src, source } = config;
67+
const { isProd, isServer } = env;
68+
6669
// Apply base-level `env` values
67-
env.dest = resolve(cwd, env.dest || 'build');
68-
env.manifest = readJson(source('manifest.json')) || {};
69-
env.pkg = readJson(resolve(cwd, 'package.json')) || {};
70+
config.dest = resolve(cwd, config.dest || 'build');
71+
config.manifest = readJson(source('manifest.json')) || {};
72+
config.pkg = readJson(resolve(cwd, 'package.json')) || {};
7073

7174
// use browserslist config environment, config default, or default browsers
7275
// default browsers are '> 0.5%, last 2 versions, Firefox ESR, not dead'
@@ -150,7 +153,7 @@ module.exports = function createBaseConfig(env) {
150153
use: [
151154
{
152155
loader: require.resolve('babel-loader'),
153-
options: createBabelConfig(env),
156+
options: createBabelConfig(config, isProd),
154157
},
155158
require.resolve('source-map-loader'),
156159
],
@@ -296,7 +299,7 @@ module.exports = function createBaseConfig(env) {
296299
new RemoveEmptyScriptsPlugin(),
297300
new MiniCssExtractPlugin({
298301
filename:
299-
isProd && !env.isServer ? '[name].[contenthash:5].css' : '[name].css',
302+
isProd && !isServer ? '[name].[contenthash:5].css' : '[name].css',
300303
chunkFilename: isProd
301304
? '[name].chunk.[contenthash:5].css'
302305
: '[name].chunk.css',

0 commit comments

Comments
 (0)