Fix webpack HMR
This commit is contained in:
@@ -1,3 +1,7 @@
|
|||||||
|
### 9.0.0-alpha.3: September 11th, 2016
|
||||||
|
* Fix webpack HMR ([#1713](https://github.com/roots/sage/issues/1713))
|
||||||
|
* Remove minor edits from CHANGELOG.md ([3516629](https://github.com/roots/sage/commit/3516629))
|
||||||
|
|
||||||
### 9.0.0-alpha.2: September 4th, 2016
|
### 9.0.0-alpha.2: September 4th, 2016
|
||||||
* Refactor build routine ([#1703](https://github.com/roots/sage/pull/1703))
|
* Refactor build routine ([#1703](https://github.com/roots/sage/pull/1703))
|
||||||
* Update `_grid.scss` to use `@include make-col-ready()` mixin ([#1706](https://github.com/roots/sage/pull/1706))
|
* Update `_grid.scss` to use `@include make-col-ready()` mixin ([#1706](https://github.com/roots/sage/pull/1706))
|
||||||
@@ -16,7 +20,7 @@
|
|||||||
* Refactor functions.php ([eae36be](https://github.com/roots/sage/commit/eae36be))
|
* Refactor functions.php ([eae36be](https://github.com/roots/sage/commit/eae36be))
|
||||||
* Rework template wrapper, bring back template_part() ([#1678](https://github.com/roots/sage/pull/1678))
|
* Rework template wrapper, bring back template_part() ([#1678](https://github.com/roots/sage/pull/1678))
|
||||||
* Remove unused static variable in Wrapper ([9bfdd5a](https://github.com/roots/sage/commit/9bfdd5a))
|
* Remove unused static variable in Wrapper ([9bfdd5a](https://github.com/roots/sage/commit/9bfdd5a))
|
||||||
* Remove path.extname() check ([#1673](https://github.com/roots/sage/pull/1673))
|
* Remove `path.extname()` check ([#1673](https://github.com/roots/sage/pull/1673))
|
||||||
* Updated to align with the Bootstrap 4 docs ([#1667](https://github.com/roots/sage/pull/1667))
|
* Updated to align with the Bootstrap 4 docs ([#1667](https://github.com/roots/sage/pull/1667))
|
||||||
* Add `npm prune` to Travis CI ([#1663](https://github.com/roots/sage/pull/1663))
|
* Add `npm prune` to Travis CI ([#1663](https://github.com/roots/sage/pull/1663))
|
||||||
* Bootstrap NPM ^4.0.0-alpha.2 ([#1650](https://github.com/roots/sage/pull/1650))
|
* Bootstrap NPM ^4.0.0-alpha.2 ([#1650](https://github.com/roots/sage/pull/1650))
|
||||||
|
|||||||
18
README.md
18
README.md
@@ -86,8 +86,8 @@ You now have all the necessary dependencies to run the build process.
|
|||||||
|
|
||||||
### Build commands
|
### Build commands
|
||||||
|
|
||||||
|
* `npm start` — Compile assets when file changes are made, start BrowserSync session
|
||||||
* `npm run build` — Compile and optimize the files in your assets directory
|
* `npm run build` — Compile and optimize the files in your assets directory
|
||||||
* `npm run start` — Compile assets when file changes are made, start BrowserSync session
|
|
||||||
* `npm run build:production` — Compile assets for production
|
* `npm run build:production` — Compile assets for production
|
||||||
|
|
||||||
#### Additional commands
|
#### Additional commands
|
||||||
@@ -98,7 +98,7 @@ You now have all the necessary dependencies to run the build process.
|
|||||||
|
|
||||||
### Using BrowserSync
|
### Using BrowserSync
|
||||||
|
|
||||||
To use BrowserSync during `npm run start` you need to update `devUrl` at the bottom of `assets/config.json` to reflect your local development hostname.
|
To use BrowserSync during `npm start` you need to update `devUrl` at the bottom of `assets/config.json` to reflect your local development hostname.
|
||||||
|
|
||||||
If your local development URL is `https://project-name.dev`, update the file to read:
|
If your local development URL is `https://project-name.dev`, update the file to read:
|
||||||
```json
|
```json
|
||||||
@@ -115,6 +115,20 @@ If you are not using [Bedrock](https://roots.io/bedrock/), update `publicPath` t
|
|||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
By default, BrowserSync will use webpack's [HMR](https://webpack.github.io/docs/hot-module-replacement.html), which won't trigger a page reload in your browser.
|
||||||
|
|
||||||
|
If you would like to force BrowserSync to reload the page whenever certain file types are edited, then add them to `watch` in `assets/config.json`.
|
||||||
|
|
||||||
|
```json
|
||||||
|
...
|
||||||
|
"watch": [
|
||||||
|
"assets/scripts/**/*.js",
|
||||||
|
"templates/**/*.php",
|
||||||
|
"src/**/*.php"
|
||||||
|
],
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
Sage 8 documentation is available at [https://roots.io/sage/docs/](https://roots.io/sage/docs/).
|
Sage 8 documentation is available at [https://roots.io/sage/docs/](https://roots.io/sage/docs/).
|
||||||
|
|||||||
@@ -47,4 +47,5 @@ module.exports = mergeWithConcat(config, {
|
|||||||
.map(file => path.join(config.paths.assets, file));
|
.map(file => path.join(config.paths.assets, file));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
publicPath: `${config.publicPath}/${path.basename(config.paths.dist)}/`,
|
||||||
});
|
});
|
||||||
|
|||||||
21
assets/build/util/addHotMiddleware.js
Normal file
21
assets/build/util/addHotMiddleware.js
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
const qs = require('qs');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loop through webpack entry
|
||||||
|
* and add the hot middleware
|
||||||
|
* @param {Object} entry webpack entry
|
||||||
|
* @return {Object} entry with hot middleware
|
||||||
|
*/
|
||||||
|
module.exports = (entry) => {
|
||||||
|
const results = {};
|
||||||
|
const hotMiddlewareScript = `webpack-hot-middleware/client?${qs.stringify({
|
||||||
|
timeout: 20000,
|
||||||
|
reload: false,
|
||||||
|
})}`;
|
||||||
|
|
||||||
|
Object.keys(entry).forEach(name => {
|
||||||
|
results[name] = Array.isArray(entry[name]) ? entry[name].slice(0) : [entry[name]];
|
||||||
|
results[name].push(hotMiddlewareScript);
|
||||||
|
});
|
||||||
|
return results;
|
||||||
|
};
|
||||||
18
assets/build/util/assetsPluginProcessOutput.js
Normal file
18
assets/build/util/assetsPluginProcessOutput.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process AssetsPlugin output and format it
|
||||||
|
* for Sage: {"[name].[ext]":"[name]_[hash].[ext]"}
|
||||||
|
* @param {Object} assets passed by processOutput
|
||||||
|
* @return {String} JSON
|
||||||
|
*/
|
||||||
|
module.exports = (assets) => {
|
||||||
|
const results = {};
|
||||||
|
Object.keys(assets).forEach(name => {
|
||||||
|
Object.keys(assets[name]).forEach(ext => {
|
||||||
|
const filename = `${path.dirname(assets[name][ext])}/${path.basename(`${name}.${ext}`)}`;
|
||||||
|
results[filename] = assets[name][ext];
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return JSON.stringify(results);
|
||||||
|
};
|
||||||
@@ -8,22 +8,28 @@ const ImageminPlugin = require('imagemin-webpack-plugin').default;
|
|||||||
const imageminMozjpeg = require('imagemin-mozjpeg');
|
const imageminMozjpeg = require('imagemin-mozjpeg');
|
||||||
|
|
||||||
const mergeWithConcat = require('./util/mergeWithConcat');
|
const mergeWithConcat = require('./util/mergeWithConcat');
|
||||||
|
const addHotMiddleware = require('./util/addHotMiddleware');
|
||||||
const webpackConfigProduction = require('./webpack.config.production');
|
const webpackConfigProduction = require('./webpack.config.production');
|
||||||
const webpackConfigWatch = require('./webpack.config.watch');
|
const webpackConfigWatch = require('./webpack.config.watch');
|
||||||
const config = require('./config');
|
const config = require('./config');
|
||||||
|
|
||||||
const publicPath = `${config.publicPath}/${path.basename(config.paths.dist)}/`;
|
|
||||||
const assetsFilenames = (config.enabled.cacheBusting) ? config.cacheBusting : '[name]';
|
const assetsFilenames = (config.enabled.cacheBusting) ? config.cacheBusting : '[name]';
|
||||||
const sourceMapQueryStr = (config.enabled.sourceMaps) ? '+sourceMap' : '-sourceMap';
|
const sourceMapQueryStr = (config.enabled.sourceMaps) ? '+sourceMap' : '-sourceMap';
|
||||||
|
|
||||||
const jsLoader = {
|
const jsLoader = {
|
||||||
test: /\.js$/,
|
test: /\.js$/,
|
||||||
exclude: [/(node_modules|bower_components)(?)/],
|
exclude: [/(node_modules|bower_components)(?)/],
|
||||||
loaders: [`babel?presets[]=${path.resolve('./node_modules/babel-preset-es2015')}&cacheDirectory`],
|
loaders: [{
|
||||||
|
loader: 'babel',
|
||||||
|
query: {
|
||||||
|
presets: [[path.resolve('./node_modules/babel-preset-es2015'), { modules: false }]],
|
||||||
|
cacheDirectory: true,
|
||||||
|
},
|
||||||
|
}],
|
||||||
};
|
};
|
||||||
|
|
||||||
if (config.enabled.watcher) {
|
if (config.enabled.watcher) {
|
||||||
jsLoader.loaders.unshift('monkey-hot');
|
jsLoader.loaders.unshift('monkey-hot?sourceType=module');
|
||||||
}
|
}
|
||||||
|
|
||||||
const webpackConfig = {
|
const webpackConfig = {
|
||||||
@@ -32,7 +38,7 @@ const webpackConfig = {
|
|||||||
devtool: (config.enabled.sourceMaps ? '#source-map' : undefined),
|
devtool: (config.enabled.sourceMaps ? '#source-map' : undefined),
|
||||||
output: {
|
output: {
|
||||||
path: config.paths.dist,
|
path: config.paths.dist,
|
||||||
publicPath,
|
publicPath: config.publicPath,
|
||||||
filename: `scripts/${assetsFilenames}.js`,
|
filename: `scripts/${assetsFilenames}.js`,
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
@@ -148,11 +154,6 @@ const webpackConfig = {
|
|||||||
Tether: 'tether',
|
Tether: 'tether',
|
||||||
'window.Tether': 'tether',
|
'window.Tether': 'tether',
|
||||||
}),
|
}),
|
||||||
new webpack.DefinePlugin({
|
|
||||||
WEBPACK_PUBLIC_PATH: (config.enabled.watcher)
|
|
||||||
? JSON.stringify(publicPath)
|
|
||||||
: false,
|
|
||||||
}),
|
|
||||||
new webpack.LoaderOptionsPlugin({
|
new webpack.LoaderOptionsPlugin({
|
||||||
minimize: config.enabled.minify,
|
minimize: config.enabled.minify,
|
||||||
debug: config.enabled.watcher,
|
debug: config.enabled.watcher,
|
||||||
@@ -181,19 +182,15 @@ if (config.env.production) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (config.enabled.watcher) {
|
if (config.enabled.watcher) {
|
||||||
module.exports = mergeWithConcat(webpackConfig, webpackConfigWatch);
|
module.exports = mergeWithConcat(webpackConfig, webpackConfigWatch, {
|
||||||
|
entry: addHotMiddleware(webpackConfig.entry),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.enabled.uglifyJs) {
|
if (config.enabled.uglifyJs) {
|
||||||
module.exports.plugins.push(
|
module.exports.plugins.push(
|
||||||
new webpack.optimize.UglifyJsPlugin({
|
new webpack.optimize.UglifyJsPlugin({
|
||||||
compress: config.enabled.minify ? {
|
|
||||||
drop_debugger: true,
|
|
||||||
dead_code: true,
|
|
||||||
warnings: false,
|
|
||||||
} : false,
|
|
||||||
sourceMap: config.enabled.sourceMaps,
|
sourceMap: config.enabled.sourceMaps,
|
||||||
output: { comments: false },
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,34 +1,17 @@
|
|||||||
const AssetsPlugin = require('assets-webpack-plugin');
|
const AssetsPlugin = require('assets-webpack-plugin');
|
||||||
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
|
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
|
||||||
const cssnano = require('cssnano');
|
const cssnano = require('cssnano');
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
|
const processOutput = require('./util/assetsPluginProcessOutput');
|
||||||
const config = require('./config');
|
const config = require('./config');
|
||||||
|
|
||||||
/**
|
|
||||||
* Process AssetsPlugin output and format it
|
|
||||||
* for Sage: {"[name].[ext]":"[name]_[hash].[ext]"}
|
|
||||||
* @param {Object} assets passed by processOutput
|
|
||||||
* @return {String} JSON
|
|
||||||
*/
|
|
||||||
const assetsPluginProcessOutput = (assets) => {
|
|
||||||
const results = {};
|
|
||||||
Object.keys(assets).forEach(name => {
|
|
||||||
Object.keys(assets[name]).forEach(ext => {
|
|
||||||
const filename = `${path.dirname(assets[name][ext])}/${path.basename(`${name}.${ext}`)}`;
|
|
||||||
results[filename] = assets[name][ext];
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return JSON.stringify(results);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
plugins: [
|
plugins: [
|
||||||
new AssetsPlugin({
|
new AssetsPlugin({
|
||||||
path: config.paths.dist,
|
path: config.paths.dist,
|
||||||
filename: 'assets.json',
|
filename: 'assets.json',
|
||||||
fullPath: false,
|
fullPath: false,
|
||||||
processOutput: assetsPluginProcessOutput,
|
processOutput,
|
||||||
}),
|
}),
|
||||||
new OptimizeCssAssetsPlugin({
|
new OptimizeCssAssetsPlugin({
|
||||||
cssProcessor: cssnano,
|
cssProcessor: cssnano,
|
||||||
|
|||||||
@@ -1,21 +1,24 @@
|
|||||||
const BrowserSyncPlugin = require('browser-sync-webpack-plugin');
|
const webpack = require('webpack');
|
||||||
const url = require('url');
|
const BrowserSyncPlugin = require('./webpack.plugin.browsersync');
|
||||||
|
|
||||||
const config = require('./config');
|
const config = require('./config');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
output: { pathinfo: true },
|
output: { pathinfo: true },
|
||||||
debug: true,
|
debug: true,
|
||||||
devTool: 'cheap-module-source-map',
|
devtool: '#cheap-module-source-map',
|
||||||
plugins: [
|
plugins: [
|
||||||
|
new webpack.optimize.OccurrenceOrderPlugin(),
|
||||||
|
new webpack.HotModuleReplacementPlugin(),
|
||||||
|
new webpack.NoErrorsPlugin(),
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
WEBPACK_PUBLIC_PATH: JSON.stringify(config.publicPath),
|
||||||
|
}),
|
||||||
new BrowserSyncPlugin({
|
new BrowserSyncPlugin({
|
||||||
host: url.parse(config.proxyUrl).hostname,
|
target: config.devUrl,
|
||||||
port: url.parse(config.proxyUrl).port,
|
publicPath: config.publicPath,
|
||||||
proxy: config.devUrl,
|
proxyUrl: config.proxyUrl,
|
||||||
files: [
|
browserSyncOptions: { files: config.watch },
|
||||||
'templates/**/*.php',
|
|
||||||
'src/**/*.php',
|
|
||||||
],
|
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
55
assets/build/webpack.plugin.browsersync.js
Normal file
55
assets/build/webpack.plugin.browsersync.js
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
'use strict'; // eslint-disable-line strict
|
||||||
|
|
||||||
|
const webpackDevMiddleware = require('webpack-dev-middleware');
|
||||||
|
const webpackHotMiddleware = require('webpack-hot-middleware');
|
||||||
|
const browserSync = require('browser-sync');
|
||||||
|
const url = require('url');
|
||||||
|
|
||||||
|
const mergeWithConcat = require('./util/mergeWithConcat');
|
||||||
|
|
||||||
|
module.exports = class {
|
||||||
|
constructor(options) {
|
||||||
|
this.watcher = null;
|
||||||
|
this.compiler = null;
|
||||||
|
this.options = mergeWithConcat({
|
||||||
|
proxyUrl: 'https://localhost:3000',
|
||||||
|
callback() {},
|
||||||
|
}, options);
|
||||||
|
}
|
||||||
|
apply(compiler) {
|
||||||
|
if (this.options.disable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.compiler = compiler;
|
||||||
|
compiler.plugin('done', this.doneCompiling);
|
||||||
|
}
|
||||||
|
doneCompiling() {
|
||||||
|
if (!this.watcher) {
|
||||||
|
this.watcher = browserSync.create();
|
||||||
|
this.compiler.plugin('compilation', () => this.watcher.notify('Rebuilding...'));
|
||||||
|
this.start();
|
||||||
|
}
|
||||||
|
// Optionally add logic for this.watcher.reload()
|
||||||
|
}
|
||||||
|
start() {
|
||||||
|
const watcherConfig = mergeWithConcat({
|
||||||
|
host: url.parse(this.options.proxyUrl).hostname,
|
||||||
|
port: url.parse(this.options.proxyUrl).port,
|
||||||
|
proxy: {
|
||||||
|
target: this.options.target,
|
||||||
|
middleware: this.middleware(),
|
||||||
|
},
|
||||||
|
}, this.options.browserSyncOptions);
|
||||||
|
this.watcher.init(watcherConfig, this.options.callback.bind(this));
|
||||||
|
}
|
||||||
|
middleware() {
|
||||||
|
this.webpackDevMiddleware = webpackDevMiddleware(this.compiler, {
|
||||||
|
publicPath: this.options.publicPath,
|
||||||
|
stats: { colors: true },
|
||||||
|
});
|
||||||
|
this.webpackHotMiddleware = webpackHotMiddleware(this.compiler, {
|
||||||
|
log: this.watcher.notify.bind(this.watcher),
|
||||||
|
});
|
||||||
|
return [this.webpackDevMiddleware, this.webpackHotMiddleware];
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -8,6 +8,10 @@
|
|||||||
"./scripts/customizer.js"
|
"./scripts/customizer.js"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"watch": [
|
||||||
|
"templates/**/*.php",
|
||||||
|
"src/**/*.php"
|
||||||
|
],
|
||||||
"publicPath": "/app/themes/sage",
|
"publicPath": "/app/themes/sage",
|
||||||
"devUrl": "https://example.dev",
|
"devUrl": "https://example.dev",
|
||||||
"proxyUrl": "https://localhost:3000",
|
"proxyUrl": "https://localhost:3000",
|
||||||
|
|||||||
11
package.json
11
package.json
@@ -35,16 +35,15 @@
|
|||||||
"babel-core": "^6.14.0",
|
"babel-core": "^6.14.0",
|
||||||
"babel-eslint": "^6.1.2",
|
"babel-eslint": "^6.1.2",
|
||||||
"babel-loader": "^6.2.5",
|
"babel-loader": "^6.2.5",
|
||||||
"babel-preset-es2015-webpack": "^6.4.3",
|
"babel-preset-es2015": "^6.14.0",
|
||||||
"babel-register": "^6.14.0",
|
"babel-register": "^6.14.0",
|
||||||
"babel-runtime": "^6.11.6",
|
"babel-runtime": "^6.11.6",
|
||||||
"body-parser": "^1.15.2",
|
"body-parser": "^1.15.2",
|
||||||
"browser-sync": "^2.15.0",
|
"browser-sync": "^2.15.0",
|
||||||
"browser-sync-webpack-plugin": "^1.1.2",
|
|
||||||
"clean-webpack-plugin": "^0.1.10",
|
"clean-webpack-plugin": "^0.1.10",
|
||||||
"css-loader": "^0.25.0",
|
"css-loader": "^0.25.0",
|
||||||
"cssnano": "^3.7.4",
|
"cssnano": "^3.7.4",
|
||||||
"eslint": "^3.4.0",
|
"eslint": "^3.5.0",
|
||||||
"eslint-config-airbnb": "^11.0.0",
|
"eslint-config-airbnb": "^11.0.0",
|
||||||
"eslint-config-airbnb-es5": "^1.0.9",
|
"eslint-config-airbnb-es5": "^1.0.9",
|
||||||
"eslint-loader": "^1.5.0",
|
"eslint-loader": "^1.5.0",
|
||||||
@@ -59,7 +58,7 @@
|
|||||||
"imports-loader": "^0.6.5",
|
"imports-loader": "^0.6.5",
|
||||||
"lodash": "^4.15.0",
|
"lodash": "^4.15.0",
|
||||||
"minimist": "^1.2.0",
|
"minimist": "^1.2.0",
|
||||||
"monkey-hot-loader": "0.0.3",
|
"monkey-hot-loader": "github:rmarscher/monkey-hot-loader#webpack2-import",
|
||||||
"node-sass": "^3.9.3",
|
"node-sass": "^3.9.3",
|
||||||
"optimize-css-assets-webpack-plugin": "^1.3.0",
|
"optimize-css-assets-webpack-plugin": "^1.3.0",
|
||||||
"postcss": "^5.2.0",
|
"postcss": "^5.2.0",
|
||||||
@@ -70,7 +69,9 @@
|
|||||||
"sass-loader": "^4.0.2",
|
"sass-loader": "^4.0.2",
|
||||||
"style-loader": "^0.13.1",
|
"style-loader": "^0.13.1",
|
||||||
"url-loader": "^0.5.7",
|
"url-loader": "^0.5.7",
|
||||||
"webpack": "^2.1.0-beta.22"
|
"webpack": "^2.1.0-beta.22",
|
||||||
|
"webpack-dev-middleware": "^1.7.0",
|
||||||
|
"webpack-hot-middleware": "^2.12.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bootstrap": "github:twbs/bootstrap#v4-dev",
|
"bootstrap": "github:twbs/bootstrap#v4-dev",
|
||||||
|
|||||||
Reference in New Issue
Block a user