timarney / react-app-rewired

Override create-react-app webpack configs without ejecting
MIT License
9.77k stars 425 forks source link

use scripting loading in defer #580

Closed Husdady closed 2 years ago

Husdady commented 2 years ago

I need to use the defer attribute in the script tags that create-react-app generates. Instead it is blocking, I used the package: https://github.com/numical/script-ext-html-webpack-plugin, but I have a problem with it when doing build, any solution?

dawnmist commented 2 years ago

Without knowing anything at all about what you have tried, what the errors you are getting are, and what version of create-react-app (and therefore webpack) you are using, it's impossible to investigate and help much.

For example:

I'd expect that the change required in your config-overrides.js file should be something like:

const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin');

module.exports = (config, env) => {
  // Create the plugin with configuration
  const extHtmlPlugin = new ScriptExtHtmlWebpackPlugin({
    defer: ['SomeScript', 'SomeScript2']
  });

  if (config.plugins) {
    // Add the plugin to the end of the array (so it will occur after HtmlWebpackPlugin)
    config.plugins.push(extHtmlPlugin);
  }
  else {
    // This would be unexpected - config.plugins should already be defined...
    // Throw an error so that the compiling stops and notifies the developer that
    // the original webpack config provided to them is broken.
    throw "No plugins found - HtmlWebpackPlugin is required to be present first, the plugins array should not be empty!";
  }

  return config;
}

That's about all the help I can give with the information provided. If that doesn't help, please let me know what your config-overrides.js file contains, what the errors are that you are experiencing, and which version of create-react-app (or react-scripts) you are actually using. If you can provide an example repository that demonstrates the error (doesn't have to be all your source code, just a cut-down project based on a fresh CRA is fine), it'd be hugely helpful for being able to trace the issue you're experiencing.

Husdady commented 2 years ago

thanks for your answer @dawnmist. The version i use of create react app is: 4.0.3. My problem arises when applying defer attribute in generated scripts. As you can see at the bottom of the image, the attributes are not applied, these help a lot in loading the site.

image

This is my config-overrides setting:

const { alias } = require("react-app-rewire-alias");
const ScriptExtHtmlWebpackPlugin = require("script-ext-html-webpack-plugin");
const ResourceHintWebpackPlugin = require("resource-hints-webpack-plugin");

module.exports = {
  webpack: (config) => {
    alias({
      "@assets": "./public/assets",
      "@pages": "./src/pages/_exports",
      "@elements": "./src/components/elements/_exports",
      "@layout": "./src/components/layout",
      "@styles": "./src/styles",
    })(config);

    config.plugins.push(
     new ResourceHintWebpackPlugin(),
     new ScriptExtHtmlWebpackPlugin({defaultAttribute: "defer"})
)

    return config }}
dawnmist commented 2 years ago

Looking at the script-ext-html-webpack-plugin code, they appear to be using the debug library to be able to enable additional logs during the webpack compile to track what the plugin is doing. This looks like it can be turned on for the plugin by setting the environment variable DEBUG='ScriptExt' when you do the build.

If you run DEBUG='ScriptExt' yarn build, what log messages do you get that start with ScriptExtHtmlWebpackPlugin? I'm particularly interested in any output that looks like:

ScriptExtHtmlWebpackPlugin: updated to: {"tagName": "script", "defer": true, ...}

I am also particularly interested in whether there are any log messages that begin with ScriptExtHtmlWebpackPlugin at all - if there are no log message that match, it potentially indicates that the plugin isn't being run at all. If there are log messages that match, the plugin is running but somehow not producing the expected results.

Husdady commented 2 years ago

So far, the only solution is to directly alter the 'html-webpack-plugin' plugin. I don't know if the plugins: "script-ext-html-webpack-plugin" and "resource-hints-webpack-plugin" were actually applied. I leave the code that works to use the defer attribute in the generated scripts:

const { alias } = require("react-app-rewire-alias");

module.exports = {
  webpack: (config) => {
    alias({
      "@assets": "./public/assets",
      "@pages": "./src/pages/_exports",
      "@elements": "./src/components/elements/_exports",
      "@layout": "./src/components/layout",
      "@styles": "./src/styles",
    })(config);

    config.plugins[0].options.scriptLoading = "defer"

    return config;
  },
};
dawnmist commented 2 years ago

I am glad you have found an alternative solution.

Out of curiosity, were there no logs produced from script-ext-html-webpack-plugin when the build was run with the environment variable DEBUG='ScriptExt' set?

timarney commented 2 years ago

Closing --- this given it's not a bug and no recent activity.