Skip to content

Commit

Permalink
Initial Webpack DLL Support (#860)
Browse files Browse the repository at this point in the history
* Initial non-workign commit

* Initial working version

* Cleaned up config and comments

* Dynamically required DLL

* Added 'dll not built' warning to webpack dev config

* Added support for babel caching

* Removed '.babelrc.js', dynamically create babel config

* Reverted modules: false
  • Loading branch information
amilajack authored Mar 31, 2017
1 parent b64264e commit efcf462
Show file tree
Hide file tree
Showing 10 changed files with 165 additions and 30 deletions.
5 changes: 4 additions & 1 deletion .babelrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"presets": [
["env", { "targets": { "node": 6 }, "useBuiltIns": true }],
["env", {
"targets": { "node": 6 },
"useBuiltIns": true
}],
"stage-0",
"react"
],
Expand Down
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ flow-typed/
app/dist/
app/main.js
node_modules
dll
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ app/bundle.js.map
app/style.css
app/style.css.map
dist
dll
main.js
main.js.map

Expand Down
17 changes: 14 additions & 3 deletions app/app.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,38 @@
<meta charset="utf-8">
<title>Hello Electron React!</title>
<script>
(function() {
(() => {
if (!process.env.HOT) {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = './dist/style.css';
// HACK: Writing the script path should be done with webpack
document.getElementsByTagName('head')[0].appendChild(link);
}
}());
})();
</script>
</head>
<body>
<div id="root"></div>
<script>
{
// Dynamically include DLL if in development
if (process.env.NODE_ENV === 'development') {
const dllScript = document.createElement('script');
dllScript.src = '../dll/vendor.dll.js';
document.body.appendChild(dllScript);
}

// Dynamically insert the renderer process
const script = document.createElement('script');
const port = process.env.PORT || 3000;

script.src = (process.env.HOT)
? 'http://localhost:' + port + '/dist/bundle.js'
: './dist/bundle.js';
// HACK: Writing the script path should be done with webpack

// @HACK: Writing the script path should be done
// with HtmlWebpackPlugin
document.body.appendChild(script);
}
</script>
Expand Down
15 changes: 9 additions & 6 deletions app/main.development.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@
import { app, BrowserWindow } from 'electron';
import MenuBuilder from './menu';


/* eslint global-require: 1, flowtype-errors/show-errors: 0 */

let mainWindow = null;

if (process.env.NODE_ENV === 'production') {
const sourceMapSupport = require('source-map-support'); // eslint-disable-line
const sourceMapSupport = require('source-map-support');
sourceMapSupport.install();
}

if (process.env.NODE_ENV === 'development') {
require('electron-debug')(); // eslint-disable-line global-require
const path = require('path'); // eslint-disable-line
const p = path.join(__dirname, '..', 'app', 'node_modules'); // eslint-disable-line
require('module').globalPaths.push(p); // eslint-disable-line
require('electron-debug')();
const path = require('path');
const p = path.join(__dirname, '..', 'app', 'node_modules');
require('module').globalPaths.push(p);
}

app.on('window-all-closed', () => {
Expand All @@ -23,7 +26,7 @@ app.on('window-all-closed', () => {

const installExtensions = async () => {
if (process.env.NODE_ENV === 'development') {
const installer = require('electron-devtools-installer'); // eslint-disable-line global-require
const installer = require('electron-devtools-installer');

const extensions = [
'REACT_DEVELOPER_TOOLS',
Expand Down
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@
"test-e2e": "cross-env NODE_ENV=test BABEL_DISABLE_CACHE=1 node --trace-warnings ./test/runTests.js e2e",
"lint": "eslint --cache --format=node_modules/eslint-formatter-pretty .",
"lint-fix": "npm run lint -- --fix",
"hot-server": "cross-env NODE_ENV=development node --trace-warnings -r babel-register ./node_modules/webpack-dev-server/bin/webpack-dev-server --config ./webpack.config.development.js",
"hot-server": "cross-env NODE_ENV=development node --trace-warnings -r babel-register ./node_modules/webpack-dev-server/bin/webpack-dev-server --config webpack.config.development.js",
"build": "npm run build-main && npm run build-renderer",
"build-dll": "cross-env NODE_ENV=production node --trace-warnings -r babel-register ./node_modules/webpack/bin/webpack --config webpack.config.dll.js --progress --profile --colors",
"build-main": "cross-env NODE_ENV=production node --trace-warnings -r babel-register ./node_modules/webpack/bin/webpack --config webpack.config.electron.js --progress --profile --colors",
"build-renderer": "cross-env NODE_ENV=production node --trace-warnings -r babel-register ./node_modules/webpack/bin/webpack --config webpack.config.production.js --progress --profile --colors",
"build": "npm run build-main && npm run build-renderer",
"start": "cross-env NODE_ENV=production electron ./app/",
"flow": "flow",
"flow-typed": "flow-typed install",
"start-hot": "cross-env HOT=1 NODE_ENV=development electron -r babel-register -r babel-polyfill ./app/main.development",
"postinstall": "concurrently \"install-app-deps\" \"node node_modules/fbjs-scripts/node/check-dev-engines.js package.json\"",
"postinstall": "concurrently \"npm run build-dll\" \"install-app-deps\" \"node node_modules/fbjs-scripts/node/check-dev-engines.js package.json\"",
"dev": "cross-env START_HOT=1 npm run hot-server",
"package": "npm run build && build --publish never",
"package-win": "npm run build && build --win --x64",
Expand Down Expand Up @@ -131,6 +132,7 @@
"babel-register": "^6.22.0",
"babili-webpack-plugin": "^0.0.11",
"boiler-room-custodian": "^0.6.1",
"chalk": "^1.1.3",
"concurrently": "^3.1.0",
"cross-env": "^3.1.4",
"cross-spawn": "^5.0.1",
Expand Down
9 changes: 7 additions & 2 deletions webpack.config.base.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,13 @@ export default {
module: {
rules: [{
test: /\.jsx?$/,
use: 'babel-loader',
exclude: /node_modules/
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true
}
}
}]
},

Expand Down
70 changes: 56 additions & 14 deletions webpack.config.development.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,32 @@
/* eslint-disable max-len */
/* eslint global-require: 0, import/no-dynamic-require: 0 */

/**
* Build config for development process that uses Hot-Module-Replacement
* https://webpack.js.org/concepts/hot-module-replacement/
*/

import path from 'path';
import fs from 'fs';
import webpack from 'webpack';
import chalk from 'chalk';
import merge from 'webpack-merge';
import { spawn } from 'child_process';
import baseConfig from './webpack.config.base';

const port = process.env.PORT || 3000;
const publicPath = `http://localhost:${port}/dist`;
const dll = path.resolve(process.cwd(), 'dll');
const manifest = path.resolve(dll, 'vendor.json');

/**
* Warn if the DLL is not built
*/
if (!(fs.existsSync(dll) && fs.existsSync(manifest))) {
console.log(chalk.white.bgRed.bold(
'The DLL manifest is missing. Please run `npm run build-dll`'
));
process.exit(0);
}

export default merge(baseConfig, {
devtool: 'inline-source-map',
Expand Down Expand Up @@ -107,9 +123,21 @@ export default merge(baseConfig, {
},

plugins: [
// https://webpack.js.org/concepts/hot-module-replacement/
new webpack.HotModuleReplacementPlugin(),
new webpack.DllReferencePlugin({
context: process.cwd(),
manifest: require(manifest),
sourceType: 'var',
}),

/**
* https://webpack.js.org/concepts/hot-module-replacement/
*/
new webpack.HotModuleReplacementPlugin({
multiStep: true
}),

new webpack.NoEmitOnErrorsPlugin(),

/**
* Create global constants which can be configured at compile time.
*
Expand All @@ -125,28 +153,42 @@ export default merge(baseConfig, {
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development')
}),
// turn debug mode on.

new webpack.LoaderOptionsPlugin({
debug: true
}),
})
],

/**
* https://github.com/chentsulin/webpack-target-electron-renderer#how-this-module-works
*/
target: 'electron-renderer',

devServer: {
port,
publicPath,
compress: true,
noInfo: true,
stats: 'errors-only',
inline: true,
lazy: false,
hot: true,
inline: false,
historyApiFallback: true,
headers: { 'Access-Control-Allow-Origin': '*' },
contentBase: path.join(__dirname, 'dist'),
publicPath,
watchOptions: {
aggregateTimeout: 300,
poll: 100
},
historyApiFallback: {
verbose: true,
disableDotRule: false,
},
setup() {
if (process.env.START_HOT) {
spawn('npm', ['run', 'start-hot'], { shell: true, env: process.env, stdio: 'inherit' })
.on('close', code => process.exit(code))
.on('error', spawnError => console.error(spawnError));
spawn(
'npm',
['run', 'start-hot'],
{ shell: true, env: process.env, stdio: 'inherit' }
)
.on('close', code => process.exit(code))
.on('error', spawnError => console.error(spawnError));
}
}
},
Expand Down
68 changes: 68 additions & 0 deletions webpack.config.dll.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import webpack from 'webpack';
import path from 'path';
import merge from 'webpack-merge';
import baseConfig from './webpack.config.base';
import { dependencies } from './package.json';

const dist = path.resolve(process.cwd(), 'dll');

export default merge(baseConfig, {
context: process.cwd(),

devtool: 'eval',

target: 'electron-renderer',

resolve: {
modules: [
'app',
'node_modules',
],
},

entry: {
vendor: [
'babel-polyfill',
...Object.keys(dependencies)
]
.filter(dependency => dependency !== 'font-awesome'),
},

output: {
library: 'vendor',
path: dist,
filename: '[name].dll.js',
libraryTarget: 'var'
},

plugins: [
new webpack.DllPlugin({
path: path.join(dist, '[name].json'),
name: '[name]',
}),

/**
* Create global constants which can be configured at compile time.
*
* Useful for allowing different behaviour between development builds and
* release builds
*
* NODE_ENV should be production so that modules do not perform certain
* development checks
*/
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('development'),
}),

new webpack.LoaderOptionsPlugin({
debug: true,
options: {
context: path.resolve(process.cwd(), 'app'),
output: {
path: path.resolve(process.cwd(), 'dll'),
},
},
})
],
externals: ['fsevents', 'crypto-browserify']
});
1 change: 0 additions & 1 deletion webpack.config.production.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,5 @@ export default merge(baseConfig, {
})
],

// https://github.com/chentsulin/webpack-target-electron-renderer#how-this-module-works
target: 'electron-renderer'
});

0 comments on commit efcf462

Please sign in to comment.