Skip to content

Commit 4f1480c

Browse files
committed
fix: Make the built server able to run from a different directory than the one it was built in
Path of log & build dir are now relative to the current running bundles instead of absolute based on where they were while building
1 parent 99ea978 commit 4f1480c

File tree

3 files changed

+63
-3
lines changed

3 files changed

+63
-3
lines changed

src/internals/webpack/WebpackBase.js

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// @flow
22

3+
import path from 'path';
34
import minimist from 'minimist';
45
import React from 'react';
56
import chalk from 'chalk';
@@ -125,6 +126,10 @@ export default class WebpackBase {
125126
hints: false,
126127
},
127128
target: this.isServer() ? 'node' : 'web',
129+
node: {
130+
// don't transform __dirname when running inside Node.
131+
__dirname: !this.isServer(),
132+
},
128133
resolve: {
129134
modules: ['node_modules'],
130135
extensions: [
@@ -387,12 +392,11 @@ export default class WebpackBase {
387392

388393
const programArgv = minimist(argv['--'] || []);
389394

390-
const definedVariables = {
395+
const definedVariables: Object = {
391396
'process.env.SIDE': SIDE,
392397
'process.env.BUILD_ENV': NODE_ENV,
393398
'process.env.PROCESS_NAME': JSON.stringify(`${projectMetadata.name} (${this.isServer() ? 'server' : 'client'})`),
394399
$$RJS_VARS$$: {
395-
FRAMEWORK_CONFIG: JSON.stringify(frameworkConfig),
396400
FRAMEWORK_METADATA: JSON.stringify(frameworkMetadata),
397401
PROJECT_METADATA: JSON.stringify(projectMetadata),
398402
PARSED_ARGV: JSON.stringify(programArgv),
@@ -406,6 +410,33 @@ export default class WebpackBase {
406410
NODE_ENV,
407411
},
408412
};
413+
} else {
414+
const outputDirectory = getWebpackSettings(this.isServer()).output.path;
415+
416+
// we only pass build & logs to bundled code
417+
// as they are the only folders that NEED to exist for the
418+
// app to run.
419+
// Using anything else MUST be an error.
420+
421+
// We don't give any information to the client bundle as they cannot interact
422+
// with the filesystem at all and trying to MUST be an error too.
423+
424+
// We give the path relative to the output directory so the project can be
425+
// moved around freely after being built. This can happen when updating a live app: The app will be built
426+
// in a temporary folder then moved to its final destination.
427+
428+
// The path relative path will be transformed into an absolute path at runtime.
429+
430+
// all executed JS files will be located at the root of outputDirectory, so we the new absolute path
431+
// will be the correct one no matter which bundle produces it.
432+
const FRAMEWORK_CONFIG = {
433+
directories: {
434+
logs: path.relative(outputDirectory, frameworkConfig.directories.logs),
435+
build: path.relative(outputDirectory, frameworkConfig.directories.build),
436+
},
437+
};
438+
439+
definedVariables.$$RJS_VARS$$.FRAMEWORK_CONFIG = JSON.stringify(FRAMEWORK_CONFIG);
409440
}
410441

411442
return definedVariables;

src/shared/framework-config/index.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
// @flow
22

3+
/**
4+
* @module framework-config
5+
*
6+
* Version for internal tools (cli, builders).
7+
*
8+
* DO NOT use in client or server bundle.
9+
*/
10+
311
import fs from 'fs';
412
import mkdirp from 'mkdirp';
513
import { merge } from 'lodash';
Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,28 @@
1+
/**
2+
* @module framework-config
3+
*
4+
* Version for built server bundles.
5+
*
6+
* DO NOT use in client bundle.
7+
* DO NOT use in internal tools (cli, builders).
8+
*/
9+
10+
import path from 'path';
111
import { FrameworkConfigStruct } from './framework-config-type';
212

3-
// Webpack DefinePlugin
413
// noinspection JSUnresolvedVariable
514
const config: FrameworkConfigStruct = $$RJS_VARS$$.FRAMEWORK_CONFIG; // eslint-disable-line no-undef
615

16+
// Once built this will look like:
17+
// const config = {"directories":{"logs":"..","build":".."}};
18+
// The variable is injected using Webpack's DefinePlugin (see WebpackBase).
19+
20+
for (const dirName of Object.keys(config.directories)) {
21+
// File paths have been transformed into relative paths before being injected so the app directory is not hardcoded.
22+
// Here we convert them back into absolute path using the correct app directory
23+
// for compatibility with the rest of the app.
24+
// More info in WebpackBase where we inject the variables.
25+
config.directories[dirName] = path.resolve(__dirname, config.directories[dirName]);
26+
}
27+
728
export default config;

0 commit comments

Comments
 (0)