s-KaiNet / spfx-fast-serve

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

Running solution via spfx-fast-serve loads woff2 icons but not via gulp #98

Closed sliziky closed 1 year ago

sliziky commented 1 year ago

Hi, this is more of a question than an issue.

Long story short, running the solution via gulp serve won't load the woff2 icons even though the webpack is configured to do so.

When I configure the fast-serve webpack the same, then the solution running via spfx-fast-serve will load the woff2 icons in hosted workbench.

Unfortunately building the solution via gulp build.. wont make the solution load woff2. What could be the solution here?

gulpfile.js

'use strict';

const gulp = require('gulp');
const build = require('@microsoft/sp-build-web');
build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`);

build.configureWebpack.mergeConfig({
    additionalConfiguration: (generatedConfiguration) => {

        generatedConfiguration.externals = generatedConfiguration.externals
            .filter(name => !(["react", "react-dom"].includes(name)));
       generatedConfiguration.module.rules.push(
      { 
        test: /\.(png|gif|woff|woff2|eot|ttf|svg)$/, 
        use: "url-loader?name=[name].[ext]"
      }
    );

        return generatedConfiguration;
    }
});
/* fast-serve */
const { addFastServe } = require("spfx-fast-serve-helpers");
addFastServe(build);
/* end of fast-serve */
build.tslint.enabled = false;
build.initialize(require('gulp'));

webpack.extends.js

/*
* User webpack settings file. You can add your own settings here.
* Changes from this file will be merged into the base webpack configuration file.
* This file will not be overwritten by the subsequent spfx-fast-serve calls.
*/

// you can add your project related webpack configuration here, it will be merged using webpack-merge module
// i.e. plugins: [new webpack.Plugin()]
const webpackConfig = {
  module: {
    rules: [
        { 
          test: /\.(png|gif|woff|woff2|eot|ttf|svg)$/, 
          use: "url-loader?name=[name].[ext]"
        }
    ]
  }
}

// for even more fine-grained control, you can apply custom webpack settings using below function
const transformConfig = function (initialWebpackConfig) {
  // transform the initial webpack config here, i.e.
  // initialWebpackConfig.plugins.push(new webpack.Plugin()); etc.
  return initialWebpackConfig;
}

module.exports = {
  webpackConfig,
  transformConfig
}
s-KaiNet commented 1 year ago

Maybe the default spfx file-loader takes precedence and the url-loader is ignored? Try to prepend url-loader instead of generatedConfiguration.module.rules.push.

sliziky commented 1 year ago

Thanks for the fast reply, although I am not quite sure what you mean by prepending it, can you give me a short code example?

s-KaiNet commented 1 year ago

I mean something like below:

function prepend(value, array) {
  var newArray = array.slice();
  newArray.unshift(value);
  return newArray;
}
generatedConfiguration.module.rules = prepend({ 
        test: /\.(png|gif|woff|woff2|eot|ttf|svg)$/, 
        use: "url-loader?name=[name].[ext]"
      }, generatedConfiguration.module.rules)
sliziky commented 1 year ago

Unfortunately nothing...but I forgot to mention that this is onprem solution...I also had this solution (not exactly this one) on shp online with the same gulpfile and there it works like a charm

gulpfile.js

'use strict';

const gulp = require('gulp');
const build = require('@microsoft/sp-build-web');

function prepend(value, array) {
  var newArray = array.slice();
  newArray.unshift(value);
  return newArray;
}

build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`);

build.configureWebpack.mergeConfig({
    additionalConfiguration: (newConfig) => {
      newConfig.module.rules = prepend({ 
        test: /\.(png|gif|woff|woff2|eot|ttf|svg)$/, 
        use: "url-loader?name=[name].[ext]"
      }, newConfig.module.rules);

        newConfig.externals = newConfig.externals
            .filter(name => !(["react", "react-dom"].includes(name)));

        return newConfig;
    }
});
/* fast-serve */
const { addFastServe } = require("spfx-fast-serve-helpers");
addFastServe(build);
/* end of fast-serve */
build.tslint.enabled = false;
build.initialize(require('gulp'));
s-KaiNet commented 1 year ago

Hmm..try to remove file-loader completely from newConfig.module.rules.

sliziky commented 1 year ago

Log of all the rules in the configureWebpack , can't see any file-loader

{ test: /\.(png|gif|woff|woff2|eot|ttf|svg)$/,
  use: 'url-loader?name=[name].[ext]' }
{ use:
   [ { loader:
        'solutionPath\\node_modules\\@microsoft\\loader-load-themed-styles\\lib\\index.js',
       options: [Object] },
     { loader:
        'solutionPath\\node_modules\\css-loader\\index.js',
       options: [Object] } ],
  test: /\.css$/ }
{ use:
   [ { loader:
        'solutionPath\\node_modules\\@microsoft\\loader-cased-file\\lib\\index.js',
       options: [Object] } ],
  test: /.(jpg|png|woff|eot|ttf|svg|gif)((\?|\#).+)?$/ }
{ use:
   [ { loader:
        'solutionPath\\node_modules\\html-loader\\index.js' } ],
  test: /\.html$/ }
{ test: /\.js$/,
  enforce: 'pre',
  use:
   'solutionPath\\node_modules\\source-map-loader\\index.js' }

so I tried to remove this one loader-cased-file but still nothing..this is the new one (just to be sure)

{ test: /\.(png|gif|woff|woff2|eot|ttf|svg)$/,
  use: 'url-loader?name=[name].[ext]' }
{ use:
   [ { loader:
        'solutionPath\\node_modules\\@microsoft\\loader-load-themed-styles\\lib\\index.js',
       options: [Object] },
     { loader:
        'solutionPath\\node_modules\\css-loader\\index.js',
       options: [Object] } ],
  test: /\.css$/ }
{ use:
   [ { loader:
        'solutionPath\\node_modules\\html-loader\\index.js' } ],
  test: /\.html$/ }
{ test: /\.js$/,
  enforce: 'pre',
  use:
   'solutionPath\\node_modules\\source-map-loader\\index.js' }
sliziky commented 1 year ago

Maybe worth mentioning that if I remove the URL rule from the fast-serve webpack & run it via fast-serve then the solution will throw this error

ERROR in ./node_modules/devextreme/dist/css/icons/dxicons.woff2 1:4
Module parse failed: Unexpected character '' (1:4)
You may need an appropriate loader to handle this file type...

How come that running gulp doesn't throw anything like this? Does gulp load it via a different loader or it simply doesn't find that woff2 file?

s-KaiNet commented 1 year ago

It seems that woff2 is not in the default list of files supported by loader-cased-file:

{ use:
   [ { loader:
        'solutionPath\\node_modules\\@microsoft\\loader-cased-file\\lib\\index.js',
       options: [Object] } ],
  test: /.(jpg|png|woff|eot|ttf|svg|gif)((\?|\#).+)?$/ }
sliziky commented 1 year ago

Isn't there a way how to package a solution via spfx-fast-serve so it would load the files correctly via url-loader? Or is this idea stupid?

s-KaiNet commented 1 year ago

Hi, unfortunately you cannot package with fast-serve, you should somehow fix the OOB build process.

github-actions[bot] commented 1 year ago

This issue has been automatically closed because we haven't received any response back. Please feel free to reopen if needed.