Roots Discourse

Sage 9 browsersync not updating right

I just tested it with webpack4 branch - and webpack watch/BrowserSync works fine.

I attempted to switch to webpack 5, got a bunch of errors on build.
Switched back to webpack 4, getting errors as well, including this one:

Preformatted textError: Cannot find module 'extract-text-webpack-plugin'

I added that yarn add extract-text-webpack-plugin

and then build again and I receive this:

 ERROR  Failed to compile with 1 errors                                            2:41:49 PM

This relative module was not found:

* ./styles/main.scss in multi ./scripts/main.js ./styles/main.scss
Built at: 01/12/2021 2:41:49 PM
                    Asset      Size      Chunks                   Chunk Names
    scripts/customizer.js  4.82 KiB  customizer  [emitted]        customizer
scripts/customizer.js.map  3.99 KiB  customizer  [emitted] [dev]  customizer
          scripts/main.js  10.7 KiB        main  [emitted]        main
      scripts/main.js.map  9.45 KiB        main  [emitted] [dev]  main
Entrypoint main = scripts/main.js scripts/main.js.map
Entrypoint customizer = scripts/customizer.js scripts/customizer.js.map
error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

after yarn start

 ERROR  Failed to compile with 1 errors                                           3:08:02 PM

This relative module was not found:

* ./styles/main.scss in multi ./resources/assets/build/util/../helpers/hmr-client.js ./scripts/main.js ./styles/main.scss
[Browsersync] Proxying: https://trellis.project.build
[Browsersync] Access URLs:
 --------------------------------------
       Local: https://localhost:3000
    External: https://192.168.0.58:3000
 --------------------------------------
          UI: http://localhost:3001
 UI External: http://localhost:3001
 --------------------------------------
[Browsersync] Watching files...
[Browsersync] Reloading Browsers...
[Browsersync] Reloading Browsers...
[Browsersync] Reloading Browsers... 

The good news is that browsersync is watching my blade files now. That’s a relief after a few years without it!
Attempting to determine what is now causing this issue and then I should be set free!

It seems that something wasn’t merged from the webpack5 PR into your existing webpack.config.js,
as with recent webpack, a different extractor should be used:

Merge the webpack.config.js and the other config files, as they contain slight modifications. This wouldn’t be noticeable when starting from scratch, but when reusing an existing webpack.config.js some parts may be overlooked.

Turns out it was the webpack preset file creating the problem.
Building and watching works great now but it appears the styles are not working at all.

I’m updating a project with tailwind 2 which was created using this:

additionally, this browsersync is constantly reloading on it’s own

Furthermore, styles are being compiled and do work:

https://trellis.project.build/app/themes/sage/dist/styles/main.css

However, none of the Tailwind classes are working. These were working before the patches were made.

I don’t know enough about all of this but it appears that perhaps webkit.config.preset.js is required for Tailwind?

I’ve put this file back in place and when I attempt to build, I get errors:

[webpack-cli] Error: Cannot find module 'extract-text-webpack-plugin'

Updated-
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const ExtractTextPlugin = require('mini-css-extract-plugin');

Build and get this error:
[webpack-cli] Error: Cannot find module 'tailwindcss'

Checked my package.json and Tailwind is missing so I added it back, updated and built again:

[webpack-cli] Failed to load '/Users/joshb/Documents/_development/_trellis/trellis.project.build/site/web/app/themes/sage/resources/assets/build/webpack.config.js'
[webpack-cli] TypeError: ExtractTextPlugin.extract is not a function

Not sure where to go from here :frowning:

Here’s the file. Really appreciate any help.

webpack.config.preset.js
'use strict'; // eslint-disable-line

const ExtractTextPlugin = require('extract-text-webpack-plugin');

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

/** Default PostCSS plugins */
let postcssPlugins = [
  require('tailwindcss')(`${config.paths.assets}/styles/tailwind.config.js`),
  require('autoprefixer')(),
];

/** Add cssnano when optimizing */
config.enabled.optimize
  ? postcssPlugins.push(
      require('cssnano')({
        preset: ['default', { discardComments: { removeAll: true } }],
      })
    )
  : false;

module.exports = {
  module: {
    rules: [
      {
        test: /\.scss$/,
        include: config.paths.assets,
        use: ExtractTextPlugin.extract({
          fallback: 'style',
          use: [
            { loader: 'cache' },
            { loader: 'css', options: { sourceMap: false } },
            {
              loader: 'postcss',
              options: {
                postcssOptions: {
                  parser: config.enabled.optimize
                  ? 'postcss-safe-parser'
                  : undefined,
                  plugins: postcssPlugins,
                  sourceMap: false,
                }
              },
            },
            {
              loader: 'resolve-url',
              options: { silent: true, sourceMap: false },
            },
            {
              loader: 'sass',
              options: { sourceComments: true, sourceMap: false },
            },
          ],
        }),
      },
    ],
  },
};

Not only that line has to be replaced but also where the new extractor is used:

I recommend that you merge the webpack.config.js using a merge tool (e.g. WinMerge).
Or post it here if you have problems with merging the changes so I can try it.

My webpack.config.js file is correct, it’s the webpack.config.preset.js file that is creating issues. If I rename/remove the preset file, everything compiles fine but tailwind is not being installed correctly. Once I have the preset file in place I get errors when compiling.

'use strict'; // eslint-disable-line

const ExtractTextPlugin = require('extract-text-webpack-plugin');

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

/** Default PostCSS plugins */
let postcssPlugins = [
  require('tailwindcss')(`${config.paths.assets}/styles/tailwind.config.js`),
  require('autoprefixer')(),
];

/** Add cssnano when optimizing */
config.enabled.optimize
  ? postcssPlugins.push(
      require('cssnano')({
        preset: ['default', { discardComments: { removeAll: true } }],
      })
    )
  : false;

module.exports = {
  module: {
    rules: [
      {
        test: /\.scss$/,
        include: config.paths.assets,
        use: ExtractTextPlugin.extract({
          fallback: 'style',
          use: [
            { loader: 'cache' },
            { loader: 'css', options: { sourceMap: false } },
            {
              loader: 'postcss',
              options: {
                postcssOptions: {
                  parser: config.enabled.optimize
                  ? 'postcss-safe-parser'
                  : undefined,
                  plugins: postcssPlugins,
                  sourceMap: false,
                }
              },
            },
            {
              loader: 'resolve-url',
              options: { silent: true, sourceMap: false },
            },
            {
              loader: 'sass',
              options: { sourceComments: true, sourceMap: false },
            },
          ],
        }),
      },
    ],
  },
};

You are right. Apparently the webpack5 PR only changes the base files, but not what is additionally added on top of these (composer create-project roots/sage selection). Hence I would have to create a PR for these additional config, as for Tailwind, Bootstrap, etc.

Adjust the merging at the very end of the base webpack.config.js:

// [...]

/**
 * During installation via sage-installer (i.e. composer create-project) some
 * presets may generate a preset specific config (webpack.config.preset.js) to
 * override some of the default options set here. We use webpack-merge to merge
 * them in. If you need to modify Sage's default webpack config, we recommend
 * that you modify this file directly, instead of creating your own preset
 * file, as there are limitations to using webpack-merge which can hinder your
 * ability to change certain options.
 */

module.exports = mergeWithRules({
  module: {
    rules: {
	  test: 'match',
	  use: {
	    loader: 'match',
	    options: 'replace',
	  },
    },
  },
})( webpackConfig, desire(`${__dirname}/webpack.config.preset`) ? desire(`${__dirname}/webpack.config.preset`) : {} )

Then use this updated tailwind variant of webpack.config.preset.js;

'use strict'; // eslint-disable-line

const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

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

module.exports = {
  module: {
    rules: [
	  {
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          { loader: 'css-loader', options: { sourceMap: config.enabled.sourceMaps } },
          {
            loader: 'postcss-loader', options: {
              postcssOptions: {
                config: path.join( __dirname, 'postcss.config.tailwind.js' ), // PostCSS tailwind specific config
                ctx: config,
              },
              sourceMap: config.enabled.sourceMaps,
            },
          },
          { loader: 'resolve-url-loader', options: { sourceMap: config.enabled.sourceMaps } },
          {
            loader: 'sass-loader', options: {
              sassOptions: {
                sourceComments: true,
              },
              sourceMap: true, //config.enabled.sourceMaps, // false causes a resolve issue
            },
          },
        ],
      },
    ],
  },
};

The PostCSS loader expects a config file, hence the tailwind-tailored PostCSS config file postcss.config.tailwind.js has to be added:

/* eslint-disable */

module.exports = (api) => {

  const cssnanoConfig = {
    preset: ['default', { discardComments: { removeAll: true } }]
  };

  return {
    parser: api.options.ctx.enabled.optimize ? 'postcss-safe-parser' : undefined,
    plugins: {
      tailwindcss: `${api.options.ctx.paths.assets}/styles/tailwind.config.js`,
      autoprefixer: true,
      cssnano: api.options.ctx.enabled.optimize ? cssnanoConfig : false,
    },
  };

};

After making the changes you provided, I am now receiving this error on build:

Error: Cannot find module 'path-exists'

Full output:

yarn run v1.22.10
$ webpack --progress --config resources/assets/build/webpack.config.js
internal/modules/cjs/loader.js:818
  throw err;
  ^

Error: Cannot find module 'path-exists'
Require stack:
- /Users/joshb/Documents/_development/_trellis/_project/trellis.project.build/site/web/app/themes/project/node_modules/find-up/index.js
- /Users/joshb/Documents/_development/_trellis/_project/trellis.project.build/site/web/app/themes/project/node_modules/import-local/node_modules/pkg-dir/index.js
- /Users/joshb/Documents/_development/_trellis/_project/trellis.project.build/site/web/app/themes/project/node_modules/import-local/index.js
- /Users/joshb/Documents/_development/_trellis/_project/trellis.project.build/site/web/app/themes/project/node_modules/webpack-cli/bin/cli.js
- /Users/joshb/Documents/_development/_trellis/_project/trellis.project.build/site/web/app/themes/project/node_modules/webpack/bin/webpack.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:815:15)
    at Function.Module._load (internal/modules/cjs/loader.js:667:27)
    at Module.require (internal/modules/cjs/loader.js:887:19)
    at require (/Users/joshb/Documents/_development/_trellis/_project/trellis.project.build/site/web/app/themes/project/node_modules/v8-compile-cache/v8-compile-cache.js:159:20)
    at Object.<anonymous> (/Users/joshb/Documents/_development/_trellis/_project/trellis.project.build/site/web/app/themes/project/node_modules/find-up/index.js:4:20)
    at Module._compile (/Users/joshb/Documents/_development/_trellis/_project/trellis.project.build/site/web/app/themes/project/node_modules/v8-compile-cache/v8-compile-cache.js:192:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Module.require (internal/modules/cjs/loader.js:887:19) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/Users/joshb/Documents/_development/_trellis/_project/trellis.project.build/site/web/app/themes/project/node_modules/find-up/index.js',
    '/Users/joshb/Documents/_development/_trellis/_project/trellis.project.build/site/web/app/themes/project/node_modules/import-local/node_modules/pkg-dir/index.js',
    '/Users/joshb/Documents/_development/_trellis/_project/trellis.project.build/site/web/app/themes/project/node_modules/import-local/index.js',
    '/Users/joshb/Documents/_development/_trellis/_project/trellis.project.build/site/web/app/themes/project/node_modules/webpack-cli/bin/cli.js',
    '/Users/joshb/Documents/_development/_trellis/_project/trellis.project.build/site/web/app/themes/project/node_modules/webpack/bin/webpack.js'
  ]
}
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

I checked out the webpack5 branch and then put a modified tailwind configuration on top of it.
You can try the tested sage 9 + webpack 5 + tailwind configuration from this repository:


Together with latest Tailwind, the dependencies require node v12 or higher, you can use a known working node version (LTS at time of writing) by invoking nvm use v14.15.3. To ensure the same node version is used among the whole team, you can create a .nvmrc with the node version as content.
I also had to modify some styles for making them compatible with latest Tailwind (new rules introduced).

@strarsis - thanks for all of that… I literally just put together my own working repo here:

Everything works fine on mine.

I just tried yours and on yarn watch it returns this error:

[webpack-cli] ReferenceError: merge is not defined

I updated the theme installation instructions as well.

Theme installation
Clone this repo and update the publicPath and devUrl in config.json

# @ resources/assets/config.json
{
  "entry": {
    "main": [
      "./scripts/main.js",
      "./styles/main.scss"
    ],
    "customizer": [
      "./scripts/customizer.js"
    ]
  },
  "publicPath": "/app/themes/sage9-wp5-tailwind2",
  "devUrl": "http://sage9-wp5-tailwind2.test",
  "proxyUrl": "http://localhost:3000",
  "cacheBusting": "[name]_[hash:8]",
  "watch": [
    "app/**/*.php",
    "config/**/*.php",
    "resources/views/**/*.php"
  ]
}
Be sure you're running node 12 first.

Navigate to your theme directory and run:

yarn && yarn build
Still in your theme, run:

composer install
Optionally update your theme details

# @ resources/style.css
/*
Theme Name:         Sage Starter Theme
Theme URI:          https://roots.io/sage/
Description:        Sage is a WordPress starter theme.
Version:            9.0.10
Author:             Roots
Author URI:         https://roots.io/
Text Domain:        sage

License:            MIT License
License URI:        http://opensource.org/licenses/MIT
*/
Now go activate theme.

@joshb: The old merge method was used for production builds and watch.
I pushed a fix commit, it should work now.

1 Like

@strarsis - I just installed a new theme and can confirm that your repo works as well.

There appears to be an issue yet with browsersync. Is it normal behavior for browsersync to constantly be reloading the browser itself? This doesn’t happen on my sage/wp/tailwind repo I created but it does on yours.

[Browsersync] Access URLs:
 --------------------------------------
       Local: https://localhost:5552
    External: https://192.168.0.58:5552
 --------------------------------------
          UI: http://localhost:3001
 UI External: http://localhost:3001
 --------------------------------------
[Browsersync] Watching files...
[Browsersync] Reloading Browsers...
[Browsersync] Reloading Browsers... (buffered 3 events)
[Browsersync] Reloading Browsers... (buffered 14 events)
[Browsersync] Reloading Browsers... (buffered 7 events)
[Browsersync] Reloading Browsers... (buffered 61 events)
[Browsersync] Reloading Browsers... (buffered 77 events)
[Browsersync] Reloading Browsers... (buffered 72 events)
[Browsersync] Reloading Browsers... (buffered 259 events)
[Browsersync] Reloading Browsers... (buffered 16 events)
[Browsersync] Reloading Browsers... (buffered 5 events)
[Browsersync] Reloading Browsers... (buffered 5 events)
[Browsersync] Reloading Browsers... (buffered 5 events)
[Browsersync] Reloading Browsers... (buffered 37 events) 

Additionally, browsersync doesn’t appear to be updating when adding new html tags, etc.
I have to hard refresh a 2 to 5 times to see the update. OR I have to build again and then refresh.

But if I add a tailwind class to a tag for example, then browsersync updates immediately.

After further use, it appears the reloading browsers is happening with my repo as well.
It reloads almost every second or two.

Makes it impossible to user the inspector.

Hm, I am unable to reproduce this issue though… E.g. when I clone the repository, configure + start a test WordPress container, install the dependencies and start watching (nvm use lts/*; nvm install; composer install; npm start), wait for the page to open and then change something, e.g. add body { background: red; } to _page.scss, the page, the page turns red. When I change it something else, e.g. body { background: blue; } the page turns blue. I don’t experience a BrowserSync reload loop.

  • Are you using HTTPS on the test server or on BrowserSync itself?
  • Are you using the Chrome browser?
  • What do you see in Developer JavaScript console, any errors/warnings, CORS errors from BrowserSync?

I am using a self signed certificate with trellis cert which is also not secure with localhost.

I am using chrome.

I dont believe I have any console errors but will confirm once I get back to my workstation

A couple of things:

First, I turned off SSL for development and provisioned. Installed your version of the theme, set up my config file, etc and ran yarn start.

Site opens up here: http://localhost:3000/ with an error:

This site can’t provide a secure connection
localhost  sent an invalid response.
ERR_SSL_PROTOCOL_ERROR

Then it continues to reload browsers:

Browsersync] Watching files...
[Browsersync] Reloading Browsers... (buffered 90 events)
[Browsersync] Reloading Browsers... (buffered 54 events)
[Browsersync] Reloading Browsers... (buffered 184 events)
[Browsersync] Reloading Browsers... (buffered 200 events)
[Browsersync] Reloading Browsers... (buffered 50 events)
[Browsersync] Reloading Browsers... (buffered 149 events)
[Browsersync] Reloading Browsers... (buffered 146 events)
[Browsersync] Reloading Browsers... (buffered 73 events)
[Browsersync] Reloading Browsers... (buffered 269 events)
[Browsersync] Reloading Browsers... (buffered 594 events)
[Browsersync] Reloading Browsers... (buffered 402 events)
[Browsersync] Reloading Browsers... (buffered 755 events)
[Browsersync] Reloading Browsers... (buffered 52 events)
[Browsersync] Reloading Browsers... (buffered 39 events)
[Browsersync] Reloading Browsers... (buffered 73 events)
[Browsersync] Reloading Browsers... (buffered 404 events)
[Browsersync] Reloading Browsers... (buffered 23 events)
[Browsersync] Reloading Browsers... (buffered 19 events)
[Browsersync] Reloading Browsers... (buffered 641 events)
[Browsersync] Reloading Browsers... (buffered 118 events)
[Browsersync] Reloading Browsers... (buffered 58 events)
[Browsersync] Reloading Browsers... (buffered 724 events)
[Browsersync] Reloading Browsers... (buffered 99 events)
[Browsersync] Reloading Browsers... (buffered 1428 events)
[Browsersync] File event [change] : dist/styles/main.css
[Browsersync] Reloading Browsers...
[Browsersync] Reloading Browsers...
[Browsersync] Reloading Browsers...
[Browsersync] Reloading Browsers...
[Browsersync] Reloading Browsers... (buffered 111 events)
[Browsersync] Reloading Browsers... (buffered 11 events)
[Browsersync] Reloading Browsers... (buffered 131 events)
[Browsersync] Reloading Browsers... (buffered 616 events)
[Browsersync] Reloading Browsers... (buffered 20 events)
[Browsersync] Reloading Browsers... (buffered 334 events)
[Browsersync] Reloading Browsers... (buffered 55 events)
[Browsersync] Reloading Browsers... (buffered 26 events)
[Browsersync] Reloading Browsers... (buffered 233 events)
[Browsersync] Reloading Browsers... (buffered 157 events)
[Browsersync] Reloading Browsers... (buffered 72 events)

I changed the proxyUrl in both config.json and build/config.js and started again but I’m still getting SSL_PROTOCOL_ERROR - http://localhost:9992/

Next I set SSL back on and provisioned again. Changed the proxyUrl’s to: https://localhost:6661
Now the site will load my proxyUrl secured but otherwise it won’t? As of now, it doesn’t appear to be reloading browsers anymore. I may have been using the incorrect node version before but I’m not sure.

It appears to be taking a long time to compile scss files though (6 seconds) and some detailed output I haven’ seen in the past.

 DONE  Compiled successfully in 6173ms                                           12:49:28 PM

assets by info 1.49 KiB [immutable]
  assets by path *.js 1.42 KiB
    asset main.8c91c23f60ab8bd9e982.hot-update.js 1.03 KiB [emitted] [immutable] [hmr] (name: main) 1 related asset
    asset customizer.8c91c23f60ab8bd9e982.hot-update.js 401 bytes [emitted] [immutable] [hmr] (name: customizer) 1 related asset
  assets by path *.json 62 bytes
    asset customizer.8c91c23f60ab8bd9e982.hot-update.json 34 bytes [emitted] [immutable] [hmr]
    asset main.8c91c23f60ab8bd9e982.hot-update.json 28 bytes [emitted] [immutable] [hmr]
assets by path scripts/*.js 508 KiB
  asset scripts/main.js 374 KiB [emitted] (name: main) 1 related asset
  asset scripts/customizer.js 133 KiB [emitted] (name: customizer) 1 related asset
asset styles/main.css 2.19 MiB [emitted] [big] (name: main) 1 related asset
Entrypoint main [big] 2.56 MiB (1.27 MiB) = styles/main.css 2.19 MiB scripts/main.js 374 KiB main.8c91c23f60ab8bd9e982.hot-update.js 1.03 KiB 3 auxiliary assets
Entrypoint customizer 134 KiB (135 KiB) = scripts/customizer.js 133 KiB customizer.8c91c23f60ab8bd9e982.hot-update.js 401 bytes 2 auxiliary assets
[Browsersync] File event [change] : dist/styles/main.css

Blade files aren’t updating perfectly either. Sometimes they update immedately, other times I have to clear yarn cache and/or yarn build, then refresh to see changes.

Some folks have mentioned in the past that it could be a file system issue but I’m running fresh installs of everything on a brand new iMac with Big Sur. Previously I was running Mohave on a Macbook and had similar issues as I am experiencing now, mostly with Blade files and browsersync.

Secondly, another strange thing is happening. I was using my version of the package yesterday. Things were mostly fine with some browser reloading issues as well, however, this morning the project had duplicates of files I was working on yesterday.

For example, header.blade.php now has another version named header.blade 2.php
Same with _header.scss or any other file I had opened yesterday.

This was happening several days ago as well, since I’ve been attempting to get this package together but I didn’t think much of it then. Figured that I made a mistake and copied files. Now that it happened overnight, I know it wasn’t something I did. I will keep an eye on this and report back if files are duplicated again.

1 Like