Sage: Enable CSS build when watching

Created on 1 Feb 2017  路  5Comments  路  Source: roots/sage

Submit a feature request or bug report

Replace any X with your information.


What is the current behavior?

With the --watch flag, webpack doesn't create dist/styles directory nor compile styles.

What is the expected or desired behavior?

Always build files, being watching them or not.

Please describe your local environment:

WordPress version: 4,7

OS: Mac El Capitan

NPM/Node version: 7

Where did the bug happen? Development or remote servers?

Development

Is there a related Discourse thread or were any utilized (please link them)?

https://discourse.roots.io/t/yarn-watch-not-generating-styles-directory/8640


Feature Request

Please provide use cases for changing the current behavior:

  • Need to commit built files (I know, I know).
  • Can't afford a continuous integration/deployment process.
  • Don't want to run yarn build:production before every commit.

Plus (not a big deal) there're always a 404 at first load for the main.css missing file, and a brief "flash of no style" before the CSS gets injected in development env.

Other relevant information:

Removing this line makes Webpack building the CSS file even when watching, but then changes aren't live-reloaded. Just read a lot of threads about this and it seems hard/impossible to have hot-reloading + files written. Any idea? Am I missing something obvious here?

Thanks.

Most helpful comment

Got it working by using https://github.com/gajus/write-file-webpack-plugin and doing the following changes:

  1. Run yarn add write-file-webpack-plugin --dev
  2. Remove dist in .gitignore (if you need to commit compiled files)
  3. Add *.hot-update.json in gitignore
  4. Edit assets/build/webpack.config.js and remove this line: disable: (config.enabled.watcher),
  5. Edit assets/build/webpack.config.watch.js:

````js
const webpack = require('webpack');
const BrowserSyncPlugin = require('browsersync-webpack-plugin');
const WriteFilePlugin = require('write-file-webpack-plugin');

const config = require('./config');

module.exports = {
devServer: {
outputPath: config.paths.dist
},
output: {
pathinfo: true,
publicPath: config.proxyUrl + config.publicPath,
},
devtool: '#cheap-module-source-map',
stats: false,
plugins: [
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
new BrowserSyncPlugin({
target: config.devUrl,
proxyUrl: config.proxyUrl,
watch: config.watch,
delay: 500,
}),
new WriteFilePlugin(),
],
};
````

Finally add this in main.js:

js // Force CSS update // https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/30#issuecomment-256958209 if (process.env.NODE_ENV !== 'production') { if (module.hot) { const reporter = window.__webpack_hot_middleware_reporter__ const success = reporter.success reporter.success = function () { document.querySelectorAll('[id*="sage"]').forEach((link) => { const nextStyleHref = link.href.replace(/(\?\d+)?$/, `?${Date.now()}`) link.href = nextStyleHref }) success() } } }

All 5 comments

the files are served from memory during a browsersync session, they will always 404 until a build

styles are automatically injected into the BS session during development. if that's not what you're seeing then you likely have a configuration issue with assets/config.json

please use https://discourse.roots.io/ for personal support requests

Got it working by using https://github.com/gajus/write-file-webpack-plugin and doing the following changes:

  1. Run yarn add write-file-webpack-plugin --dev
  2. Remove dist in .gitignore (if you need to commit compiled files)
  3. Add *.hot-update.json in gitignore
  4. Edit assets/build/webpack.config.js and remove this line: disable: (config.enabled.watcher),
  5. Edit assets/build/webpack.config.watch.js:

````js
const webpack = require('webpack');
const BrowserSyncPlugin = require('browsersync-webpack-plugin');
const WriteFilePlugin = require('write-file-webpack-plugin');

const config = require('./config');

module.exports = {
devServer: {
outputPath: config.paths.dist
},
output: {
pathinfo: true,
publicPath: config.proxyUrl + config.publicPath,
},
devtool: '#cheap-module-source-map',
stats: false,
plugins: [
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
new BrowserSyncPlugin({
target: config.devUrl,
proxyUrl: config.proxyUrl,
watch: config.watch,
delay: 500,
}),
new WriteFilePlugin(),
],
};
````

Finally add this in main.js:

js // Force CSS update // https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/30#issuecomment-256958209 if (process.env.NODE_ENV !== 'production') { if (module.hot) { const reporter = window.__webpack_hot_middleware_reporter__ const success = reporter.success reporter.success = function () { document.querySelectorAll('[id*="sage"]').forEach((link) => { const nextStyleHref = link.href.replace(/(\?\d+)?$/, `?${Date.now()}`) link.href = nextStyleHref }) success() } } }

@nicooprat 's fix also works for sage 9

I am running Sage 9.0.9, and this does not work for me. Can I clarify that the // Force CSS update code goes into the theme's /resources/assets/scripts/main.js?

@nicooprat
Should this be overwriting the main.css file content on compile from running yarn start?

@dylanjameswagner It's a bit old in my memory, but yes it should be in your main.js or any other JS file that is loaded by Webpack. The main.css content should indeed be replaced, does this work? Your browser might still load its cached version regardless the ? date parameter appended in the stylesheet URL. You can try to open the devtools and disable cache to avoid this.

Was this page helpful?
0 / 5 - 0 ratings