wingsuit-designsystem / wingsuit

Twig for Storybook
GNU General Public License v2.0
91 stars 16 forks source link

Custom loaders with wingsuit and webpack #139

Closed jowan closed 3 years ago

jowan commented 3 years ago

Hi there,

I want to load some custom svg fonts. My project is a Drupal/Twig project, and I want to load the fonts in SCSS like this:

@import '~@fortawesome/fontawesome-free/css/all.css';

as this makes most sense so to me. However, I get the error

_ERROR in ./nodemodules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.ttf 1:0 Module parse failed: Unexpected character ' ' (1:0) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders

Reading online - I believe storybook requires a custom loader (file-loader), something like the following:

{
  test: /\.(png|woff|woff2|eot|ttf|svg)$/,
  loaders: ['file'],
  include: resolve(__dirname, '../')
}

Which needs to be added to the webpack.config.js

I have been reading https://wingsuit-designsystem.github.io/configurations/custom-webpack-config/ and think that I can possibly use a preset, the override some parameters ?

Question: How would I add a custom "loader" using wingsuit's webpack please ?

thanks

christianwiedemann commented 3 years ago

Hi! I think the problem is that webpack tries to load a font file from a webfonts folder. Wingsuit uses the folder name to apply loader. For the webfont folder is no loader configured. You can easily extend the webpack with an own loader for your webfont folder:

Your tailwind config file. (Not sure if there is typo somewhere it is not tested.)

module.exports = {
  webpack: function(appConfig) {
  return {
    module: {
      rules: [

        {
          test: /.*[/|\\\\]webfonts[/|\\\\].*\.(svg|woff|woff2|eot|ttf|otf)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
          use: [
            {
              loader: 'file-loader',
              options: {
                outputPath: path.join(appConfig.assetBundleFolder, 'font'),
                name: '[name].[ext]?[hash]',
              },
            },
          ],
        },
    ]
 }
}
}

But I think a preset for webfonts would be great idea. But I think it would be better to generate a custom font instead of using fontawesome for performance reasons. What do you think?

jowan commented 3 years ago

Hi,

Thanks for the info about how to add a custom loader - I'm going to play around with that. That was exactly the info I requested.

For now I added the library to my source/styles folder and it works (presumably because of the assets.js ?) but I'd prefer to import it form the node_modules.

I am developing for Drupal, and trying to get a good model working for our frontenders. I'm coming from PHP so webpack and node is not my comfort zone at all.

My added complexity is that I need to produce a master and sub theme from one storybook. The subthemes can be manually exported, I don't expect wingsuit to cater for that. I have successfully changed the config so that it pushes the built templates from storybook to a custom theme in a Drupal installation - this is awesome.

The main issue for me now is good SCSS management in the sources folder, and a front end widget to change the "branding" or theme elements. None of the storybook plugins (cssresrouces/themes/context/toolbar) does quite what I want, but I'll figure it out.

Another major requirement is 'optimisation. Traditionally in gulp I'd do things like - look for font awesome fonts in source and create a new custom slimline font pack based on those fonts. But not sure what the entrypoint for those kind of routines would be here.

How do I hack into Webpack (or whereever) and add other gulp-like stuff (scss optimisation/js optimisation etc). ?

Great work - and thanks for your help

christianwiedemann commented 3 years ago

Quite interested in how you build your theme setup. Do you use the same patterns in all sub themes and change the path the css config.

To the fonts: What I used for custom fonts in a project is fantasticon. In my setup, I build the font in an extra step. Which is not optimal.

Here my package.json script. "build:font": "fantasticon ./source/default/patterns/01-atoms/svg/svg/icons -p fa -o ./source/default/tokens/fonts/icon -n icons -g css ",

think building fonts should be part of a wingsuit preset but not 100% sure how to do this optimal.

Hope it helps.

jowan commented 3 years ago

In reference to sub themes, patterns will be in master theme, and sub themes will (hopefully) only provide branding assets such as css and js. That is the theory anyway !

Thanks for the 'build:font' - again, that is exactly the info I need.

Not sure about fonts in presets. I would love to move away from Bootstrap 4 and Font Awesome 5 pro as they are both quite heavy but the company/fontends are locked in. It is however, a common setup.

Closing this - thanks for the pointers. I am using this toolchain now for a big project so expect more quesions!

jowan commented 3 years ago

For reference:

in wingsuit.config.js

const path = require('path');
const namespaces = require('./source/default/namespaces');

module.exports = {
  presets: ['@wingsuit-designsystem/preset-scss'],
  designSystems: {
    default: {
      namespaces,
    },
  },
  webpack: function(appConfig) {
    return {
      module: {
        rules: [
          {
            test: /.*[/|\\\\]webfonts[/|\\\\].*\.(svg|woff|woff2|eot|ttf|otf)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
            use: [
              {
                loader: 'file-loader',
                options: {
                  outputPath: path.join(appConfig.assetBundleFolder, 'webfonts'),
                  name: '[name].[ext]?[hash]',
                },
              },
            ],
          },
        ],
      },
    };
  },
};

and in main.scss (or other)

$fa-font-path: '~@fortawesome/fontawesome-free/webfonts';

@import "~@fortawesome/fontawesome-free/scss/fontawesome.scss";
@import "~@fortawesome/fontawesome-free/scss/solid.scss";
@import "~@fortawesome/fontawesome-free/scss/brands.scss";
@import "~@fortawesome/fontawesome-free/scss/regular.scss";