s-KaiNet / spfx-fast-serve

Improve your SharePoint Framework development flow by speeding up the "serve" command :rocket:
MIT License
133 stars 11 forks source link

DefinePlugin error with SPFx 1.17.3 #107

Closed pschaeflein closed 11 months ago

pschaeflein commented 11 months ago

Similar to issue #99 , the fast-serve/webpack dev server throws:

project_root\node_modules\webpack\lib\DefinePlugin.js:344
        compilation.valueCacheVersions.get(VALUE_DEP_MAIN)
                                       ^
TypeError: Cannot read properties of undefined (reading 'get')

My webpack.extend.js contains this:

const webpack = require("webpack");
const transformConfig = function (initialWebpackConfig) {
  initialWebpackConfig.plugins.push(new webpack.DefinePlugin({
    SAMPLE_DATA: JSON.stringify(true),
  }));
  return initialWebpackConfig;
};

module.exports = {
  webpackConfig,
  transformConfig
};

Relevant package.json info:

@microsoft/sp-build-web: "1.17.3"
spfx-fast-serve-helpers: "~1.17.0",

Looking in the node_modules folder, the top-level webpack is version 5.88.2, while the spfx-fast-serve/node_modules folder is version 4.44.2

Was able to work around by finding the existing Define plugin and updating that:

  const plugIns = initialWebpackConfig.plugins;
  plugIns.forEach(plugIn => {
    if (plugIn.definitions) {
      plugIn.definitions.SAMPLE_DATA = JSON.stringify(true);
    }
  });
s-KaiNet commented 11 months ago

Yeah, I noticed that issue some time ago and added a "webpack" parameter to transformConfig function:

const transformConfig = function (initialWebpackConfig, webpack) {
// use the right webpack version here
}

However, I haven't added it yet to the generator (spfx-fast-serve global tool), which I'm going to fix a bit later. But you can use this trick for 1.17 version safely.

pschaeflein commented 11 months ago

I'm not sure I understand.

It seems to me that you will provide the webpack object that was created elsewhere in the tool chain. And we should use that instead of coding a require statement.

That would likely resolve this issue, but I would prefer that fast-serve use the webpack version installed by SPFx.

Thanks.

s-KaiNet commented 11 months ago

fast-serve always uses the webpack version installed by SPFx (currently 4.44). But there is an issue in SPFx starting from 1.16 version, when some SPFx internal dependencies use webpack 5.x in their dependency trees. As a result top-level webpack version, resolved by npm is webpack@5.x (despite SPFx uses 4.x internally, it's available inside nested node_modules, if you run npm list webpack you will see all the different version installed). You can also check the versions by creating clean SPFx 1.17 webpart and adding below lines inside gulpfile.js:

const webpack = require('webpack');
console.log(webpack.version);
....
build.configureWebpack.mergeConfig({
  additionalConfiguration: (generatedConfiguration) => {
    console.log("actual version: " + build.webpack.taskConfig.webpack.version);
    return generatedConfiguration;
  }
});

The resolved version will be 5.x, but it's not the one actually used by SPFx. It leads to all those problems and tricks with DefinePlugin and potentially to some other unwanted things, if you use webpack heavily in gulpfile.js.

As a workaround for fast-serve I added webpack parameter, which is always the same webpack instance used by SPFx.

pschaeflein commented 11 months ago

Excellent, thanks for the explanation.