Skip to content

Commit a6e29d1

Browse files
committed
more fully tested this time, made other improvements too
1 parent ff05395 commit a6e29d1

File tree

6 files changed

+111
-29
lines changed

6 files changed

+111
-29
lines changed

loader.php

+15-5
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,6 @@ function infer_base_url( string $path ) {
9696
return get_theme_file_uri( substr( $path, strlen( $template_directory ) ) );
9797
}
9898

99-
if ( strpos( $path, get_template_directory() ) === 0 ) {
100-
return get_theme_file_uri( substr( $path, strlen( get_template_directory() ) ) );
101-
}
102-
10399
// Any path not known to exist within a theme is treated as a plugin path.
104100
$plugin_path = get_plugin_basedir_path();
105101
if ( strpos( $path, $plugin_path ) === 0 ) {
@@ -150,12 +146,19 @@ function enqueue_assets( $directory, $opts = [] ) {
150146
$defaults = [
151147
'base_url' => '',
152148
'handle' => basename( $directory ),
153-
'scripts' => [],
149+
'scripts' => [
150+
'react',
151+
'react-dom',
152+
],
154153
'styles' => [],
155154
];
156155

157156
$opts = wp_parse_args( $opts, $defaults );
158157

158+
// Ensure react & react-dom are dependencies.
159+
$opts['scripts'] = array_merge( $opts['scripts'], [ 'react', 'react-dom' ] );
160+
$opts['scripts'] = array_unique( $opts['scripts'] );
161+
159162
$assets = get_assets_list( $directory );
160163

161164
$base_url = $opts['base_url'];
@@ -214,6 +217,13 @@ function enqueue_assets( $directory, $opts = [] ) {
214217
}
215218
}
216219

220+
// Add the generated public path to the build directory.
221+
wp_add_inline_script(
222+
$opts['handle'],
223+
sprintf( 'var %%PUBLIC_PATH_VAR%% = %s;', wp_json_encode( $base_url . '/build/' ) ),
224+
'before'
225+
);
226+
217227
// Ensure CSS dependencies are always loaded, even when using CSS-in-JS in
218228
// development.
219229
if ( ! $has_css ) {

overrides/applyWpConfig.js

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
const paths = require('react-wp-scripts/config/paths');
2-
const HtmlWebpackPlugin = require('html-webpack-plugin');
3-
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
1+
const paths = require( 'react-wp-scripts/config/paths' );
2+
const HtmlWebpackPlugin = require( 'html-webpack-plugin' );
3+
const InterpolateHtmlPlugin = require( 'react-dev-utils/InterpolateHtmlPlugin' );
4+
const { DefinePlugin } = require( 'webpack' );
45

56
module.exports = config => {
6-
const name = ( require(paths.appPackageJson).name || `rwps${ Date.now() }` ).replace( /[-_.\W]+/g, '' );
7+
const appNameVar = require(paths.appPackageJson).name.replace( /[\W]+/g, '' );
78

89
// Remove HTML file output plugins.
910
config.plugins = config.plugins.filter( plugin => ! ( plugin instanceof HtmlWebpackPlugin ) );
@@ -16,14 +17,15 @@ module.exports = config => {
1617

1718
// Set a default JSONP function name to avoid conflicts with other instances
1819
// of react-wp-scripts using code splitting.
19-
config.output.jsonpFunction = `${name}JSONP`;
20+
config.output.jsonpFunction = `${appNameVar}JSONP`;
2021

2122
// Set some useful externals based on what WP provides in v5.x.
2223
config.externals = Object.assign( config.externals || {}, {
2324
wp: 'wp',
2425
react: 'React',
2526
'react-dom': 'ReactDOM',
2627
moment: 'moment',
28+
lodash: 'lodash',
2729
} );
2830

2931
return config;

scripts/build.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ const paths = require('../config/paths');
66

77
// Override paths on require to shortcircuit index.html requirement.
88
const requireMiddleware = require('require-middleware');
9-
requireMiddleware.use((req, next) => {
10-
if (req.request === '../config/paths' && req.path.indexOf('react-scripts/config/paths') >= 0) {
11-
return require('react-wp-scripts/config/paths');
9+
requireMiddleware.use( (req, next) => {
10+
if ( req.request.indexOf('../config/') === 0 && req.path.indexOf('react-scripts/config') >= 0 ) {
11+
return require( req.request );
1212
}
1313
next();
14-
});
14+
} );
1515

1616
const tmpPath = path.join( process.cwd(), 'public' );
1717

scripts/init.js

+68-5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ process.on( 'unhandledRejection', err => {
1111
const fs = require( 'fs-extra' );
1212
const path = require( 'path' );
1313
const chalk = require( 'chalk' );
14+
const os = require('os');
15+
const rimraf = require('rimraf');
1416

1517
const argv = require( 'minimist' )( process.argv.slice( 2 ) );
1618

@@ -29,6 +31,8 @@ module.exports = function(
2931
const reactWPScriptsPath = path.join( appPath, 'node_modules', pkgName );
3032
const appPackage = require( path.join( appPath, 'package.json' ) );
3133

34+
const useTypeScript = appPackage.dependencies['typescript'] != null;
35+
3236
const scriptsPath = path.resolve(
3337
process.cwd(),
3438
'node_modules',
@@ -43,32 +47,90 @@ module.exports = function(
4347
appPackage.scripts.start = 'react-wp-scripts start';
4448
appPackage.scripts.build = 'react-wp-scripts build';
4549

50+
// Set relative homepage
51+
appPackage.homepage = '.';
52+
4653
fs.writeFileSync(
4754
path.join( appPath, 'package.json' ),
4855
JSON.stringify( appPackage, null, 2 )
4956
);
5057

51-
// Copy the loader.php
58+
// Remove public folder
59+
rimraf( path.join( appPath, 'public' ), () => {} );
60+
61+
// Derive a var name we can use for a dynamic public path
62+
const publicPathVar = `${ appName.replace( /[\W]+/g, '' ) }BuildURL`;
63+
64+
// Get relevant file paths
65+
const publicPathPath = path.join( reactWPScriptsPath, 'template/src/publicPath.js' );
66+
const publicPathDest = path.join( appPath, 'src/publicPath.js' );
67+
const srcIndexPath = path.join( appPath, 'src', useTypeScript ? 'index.tsx' : 'index.js' );
5268
const loaderPath = path.join( reactWPScriptsPath, 'loader.php' );
69+
const loaderDest = path.join( appPath, 'react-wp-scripts.php' );
5370

54-
const destinationFile = path.join( appPath, 'react-wp-scripts.php' );
55-
fs.copy( loaderPath, destinationFile )
71+
// Replace %%PUBLIC_PATH_VAR%% and process.env.PUBLIC_URL in these files
72+
const publicPathFiles = [
73+
path.join( appPath, 'src', 'serviceWorker.js' ),
74+
publicPathDest,
75+
loaderDest,
76+
];
77+
78+
fs.copy( publicPathPath, publicPathDest )
79+
// Insert import for public path file.
80+
.then( () => new Promise( ( resolve, reject ) => {
81+
fs.readFile( srcIndexPath, 'utf8', function( err, data ) {
82+
if ( err ) {
83+
return reject( err );
84+
}
85+
86+
var result = `import './publicPath';${os.EOL}${data}`;
87+
fs.writeFile( srcIndexPath, result, 'utf8', function( err ) {
88+
if ( err ) {
89+
return reject( err );
90+
}
91+
resolve();
92+
} );
93+
} );
94+
} ) )
95+
// Copy the loader.php
96+
.then( () => fs.copy( loaderPath, loaderDest ) )
5697
.then( () => new Promise( ( resolve, reject ) => {
5798
// Replace %%NAMESPACE%% for the specified namespace
58-
fs.readFile( destinationFile, 'utf8', function( err, data ) {
99+
fs.readFile( loaderDest, 'utf8', function( err, data ) {
59100
if ( err ) {
60101
return reject( err );
61102
}
62103

63104
var result = data.replace( '%%NAMESPACE%%', namespace );
64-
fs.writeFile( destinationFile, result, 'utf8', function( err ) {
105+
fs.writeFile( loaderDest, result, 'utf8', function( err ) {
65106
if ( err ) {
66107
return reject( err );
67108
}
68109
resolve();
69110
} );
70111
} );
71112
} ) )
113+
.then( () => new Promise( ( resolve, reject ) => {
114+
publicPathFiles.forEach( ( filePath, i ) => {
115+
fs.readFile( filePath, 'utf8', function( err, data ) {
116+
if ( err ) {
117+
return reject( err );
118+
}
119+
120+
var result = data
121+
.replace( '%%PUBLIC_PATH_VAR%%', publicPathVar )
122+
.replace( 'process.env.PUBLIC_URL', publicPathVar );
123+
fs.writeFile( filePath, result, 'utf8', function( err ) {
124+
if ( err ) {
125+
return reject( err );
126+
}
127+
if ( i + 1 === publicPathFiles.length ) {
128+
return resolve();
129+
}
130+
} );
131+
} );
132+
} );
133+
} ) )
72134
.then( () => {
73135
console.log( chalk.green( 'React WP Scripts Loader copied to your project root folder.' ) );
74136
console.log( chalk.green( 'Please follow these instructions to enqueue your assets in PHP:' ) );
@@ -78,4 +140,5 @@ module.exports = function(
78140
console.log( chalk.bgRed( 'React WP Scripts loader could not be copied to your root folder. Error details:' ) );
79141
console.log( chalk.red( err ) );
80142
} );
143+
81144
};

scripts/override-start.js

+8-10
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ const createServerConfig = require( devServerConfig );
1212
const applyWpConfig = require( '../overrides/applyWpConfig' );
1313

1414
// Override paths on require to shortcircuit index.html requirement.
15-
const requireMiddleware = require( 'require-middleware' );
16-
requireMiddleware.use((req, next) => {
17-
if (req.request === '../config/paths' && req.path.indexOf( 'react-scripts/config/paths' ) >= 0) {
18-
return require( 'react-wp-scripts/config/paths' );
15+
const requireMiddleware = require('require-middleware');
16+
requireMiddleware.use( (req, next) => {
17+
if ( req.request.indexOf('../config/') === 0 && req.path.indexOf('react-scripts/config') >= 0 ) {
18+
return require( req.request );
1919
}
2020
next();
21-
});
21+
} );
2222

2323
/**
2424
* Method to apply overrides to webpack dev config object.
@@ -62,16 +62,14 @@ const overrideWebpackConfig = ( config, devServer ) => {
6262
// webpack-dev-server. This file contains a mapping of all asset filenames
6363
// to their corresponding output URI so that WordPress can load relevant
6464
// files from the dev server.
65-
config.plugins.push(new ManifestPlugin({
65+
config.plugins.push( new ManifestPlugin( {
6666
basePath: config.output.publicPath,
6767
fileName: '../asset-manifest.json',
6868
writeToFileEmit: true,
69-
}));
69+
} ) );
7070

7171
// Apply default config settings for WordPress.
72-
config = applyWpConfig( config );
73-
74-
return config;
72+
return applyWpConfig( config );
7573
};
7674

7775
/**

template/src/publicPath.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**
2+
* This file **must** be imported before anything else in
3+
* your app to ensure URLs are correctly resolved.
4+
*/
5+
6+
if ( process.env.NODE_ENV === 'production' ) {
7+
// eslint-disable-next-line
8+
__webpack_public_path__ = %%PUBLIC_PATH_VAR%%;
9+
}

0 commit comments

Comments
 (0)