Skip to content

refactor: next #1295

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Jul 14, 2021
Merged

refactor: next #1295

merged 22 commits into from
Jul 14, 2021

Conversation

cap-Bernardito
Copy link
Member

@cap-Bernardito cap-Bernardito commented Apr 27, 2021

This PR contains a:

  • bugfix
  • new feature
  • code refactor
  • test update
  • typo fix
  • metadata update

Motivation / Use-Case

  • feat: localIdentHashFunction, localIdentHashDigest, localIdentHashDigestLength options added

Breaking Changes

  • used new URL() syntax, instead import when esModules: true
  • alias.resolve with false value now generate empty dataURI, please use url.filter to keep URLs as is
  • ~ is depreacted but still supported, you can safely remove ~ from your code, due logic prefer relative then prefer absolute (only for esModules: true)
  • css-loader will be faster if you enable esModules (true by default)
  • Node.js v10 support dropped
  • webpack@4 support dropped
  • for url and import options removed type function in favor object type with filter property
  • removed importLoaders option in favor import.loaders option
  • removed modules.compileType option in favor modules.mode option, for modules.mode option added icss type
  • removed interpolate function from loader-utils in favor webpack template strings:
    • .[ext] => [ext]
    • [folder] - removed
    • [emoji] - removed
  • localIdentHashPrefix option renamed in localIdentHashSalt
  • resolve data URI only esModules: true

Additional Info

Supported template strings:

  • [name] the basename of the resource
  • [path] the path of the resource relative to the compiler.context option or modules.localIdentContext option.
  • [file] - filename and path.
  • [ext] - extension with leading .
  • [hash] - the hash of the string, generated based on localIdentHashSalt, localIdentHashFunction, localIdentHashDigest, localIdentHashDigestLength, localIdentContext, resourcePath and exportName
  • [<hashFunction>:hash:<hashDigest>:<hashDigestLength>] - hash with hash settings.
  • [local] - original class.

@codecov
Copy link

codecov bot commented Apr 27, 2021

Codecov Report

Merging #1295 (875b274) into master (ae98845) will increase coverage by 0.03%.
The diff coverage is 99.31%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1295      +/-   ##
==========================================
+ Coverage   98.31%   98.35%   +0.03%     
==========================================
  Files          11       11              
  Lines         892      972      +80     
  Branches      298      324      +26     
==========================================
+ Hits          877      956      +79     
- Misses         12       13       +1     
  Partials        3        3              
Impacted Files Coverage Δ
src/plugins/postcss-icss-parser.js 100.00% <ø> (ø)
src/plugins/postcss-import-parser.js 100.00% <ø> (ø)
src/utils.js 97.58% <99.14%> (+0.13%) ⬆️
src/index.js 100.00% <100.00%> (ø)
src/plugins/postcss-url-parser.js 97.80% <100.00%> (+0.16%) ⬆️
src/runtime/getUrl.js 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ae98845...875b274. Read the comment docs.

@alexander-akait alexander-akait marked this pull request as ready for review April 28, 2021 12:06
@sjoqvist
Copy link

I wanted starting writing new code from the next branch, but I tested it with my current project and it doesn't work for me. I'm using @mdi/font@5.9.55 and the following rule in webpack.config.js.

{
  test: /\.(eot|svg|ttf|woff2?)$/,
  use: [
    {
      loader: 'file-loader',
      options: {
        name: '[name].[ext]',
        outputPath: 'fonts/',
      },
    },
  ],
},

This setup used to create CSS rules like

src:url(/fonts/materialdesignicons-webfont.eot?#iefix&v=5.9.55)

but as of commit 899a4e3 the following is what I get.

src:url(file:///a2abc9c944c48139f361.eot?#iefix&v=5.9.55)

The same holds true for the other formats of the MDI font, of course.

Is this a mistake or a breaking change? I can't find documentation that explains what I need to do to fix it.

@alexander-akait
Copy link
Member

Do you use mini-css-extract-plugin?

@sjoqvist
Copy link

Do you use mini-css-extract-plugin?

Yes, I do.

@alexander-akait
Copy link
Member

@sjoqvist
Copy link

Update to https://github.com/webpack-contrib/mini-css-extract-plugin/releases/tag/v1.6.0

That changes the behavior, but it doesn't fix it. The corresponding output is now

src:url(/a2abc9c944c48139f361.eot?v=5.9.55)

The file a2abc9c944c48139f361.eot appears in the output with the contents

export default __webpack_public_path__ + "fonts/materialdesignicons-webfont.eot";

which causes the browser to write "Failed to decode downloaded font" in the console.

I apologize if this pull request is work in progress or if there's some changelog that I haven't read. I just wanted to report it in case the behavior was unknown.

@alexander-akait
Copy link
Member

which causes the browser to write "Failed to decode downloaded font" in the console.

it means you have broken fonts

@sjoqvist
Copy link

it means you have broken fonts

Yes, since the file /a2abc9c944c48139f361.eot contains one line of JavaScript code (the one I posted above), it's not a proper font.

/usr/share/nginx/static # file ????????????????????.*
8c9e4bb7edede879310e.woff2: ASCII text, with no line terminators
a2abc9c944c48139f361.eot:   ASCII text, with no line terminators
ea5b4187c7d3276d80ad.woff:  ASCII text, with no line terminators
f0f49284f1a83efbf8c2.ttf:   ASCII text, with no line terminators
/usr/share/nginx/static # file fonts/*
fonts/materialdesignicons-webfont.eot:   Embedded OpenType (EOT), Material Design Icons family
fonts/materialdesignicons-webfont.ttf:   TrueType Font data, 11 tables, 1st "GSUB", 16 names, Macintosh, type 1 string, Material Design IconsRegularMaterial Design IconsMaterial Design IconsVersion 1.0MaterialDesignI
fonts/materialdesignicons-webfont.woff:  Web Open Font Format, TrueType, length 465188, version 1.0
fonts/materialdesignicons-webfont.woff2: Web Open Font Format (Version 2), TrueType, length 325244, version 1.0
/usr/share/nginx/static # cat a2abc9c944c48139f361.eot 
export default __webpack_public_path__ + "fonts/materialdesignicons-webfont.eot";

But the way I see it, the CSS points out the wrong files. The files in the fonts/ directory are perfectly fine, and the CSS points to the correct files when I'm using the master branch of css-loader.

@alexander-akait
Copy link
Member

It means something wrong with your configuration, without it I can't help, anyway this issue is not related to these changes

@sjoqvist
Copy link

It means something wrong with your configuration, without it I can't help, anyway this issue is not related to these changes

My actual project is under NDA, but here's a small(-ish) project that accomplishes the same thing.

Dockerfile

FROM node:16.1.0-buster-slim
WORKDIR /usr/src/web
RUN apt-get update && apt-get install --yes file && rm -rf /var/lib/apt/lists/*
COPY package.json ./
RUN npm install
COPY main.js webpack.config.js ./
RUN $(yarn bin)/webpack --mode development
CMD set -x && head -9 build/css/* && file build/*.* build/fonts/*

main.js

import './node_modules/@mdi/font/css/materialdesignicons.css';

package.json

{
  "dependencies": {
    "@mdi/font": "5.9.55"
  },
  "devDependencies": {
    "css-loader": "webpack-contrib/css-loader#1167ab4a9f5b49e32a28f9b9645f6ab37b541f89",
    "file-loader": "6.2.0",
    "mini-css-extract-plugin": "1.6.0",
    "webpack": "5.37.0",
    "webpack-cli": "4.7.0"
  },
  "private": true
}

webpack.config.js

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

module.exports = (_env, argv) => ({
  mode: argv.mode,
  entry: {
    system: './main.js',
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
        ],
      },
      {
        test: /\.(eot|svg|ttf|woff2?)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: '[name].[ext]',
              outputPath: 'fonts/',
            },
          },
        ],
      },
    ],
  },
  output: {
    filename: 'js/[name].js',
    path: `${__dirname}/build`,
    publicPath: '/',
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: 'css/[name].css',
    }),
  ],
});

Building with docker build . -t css-loader-next and running with docker run -it --rm css-loader-next gives you the following. The links in the CSS point to files that aren't font files. The font files are where I want them to be, but they aren't referenced properly.

+ head -9 build/css/system.css
/* MaterialDesignIcons.com */
@font-face {
  font-family: "Material Design Icons";
  src: url(/a2abc9c944c48139f361.eot?v=5.9.55);
  src: url(/a2abc9c944c48139f361.eot?#iefix&v=5.9.55) format("embedded-opentype"), url(/8c9e4bb7edede879310e.woff2?v=5.9.55) format("woff2"), url(/ea5b4187c7d3276d80ad.woff?v=5.9.55) format("woff"), url(/f0f49284f1a83efbf8c2.ttf?v=5.9.55) format("truetype");
  font-weight: normal;
  font-style: normal;
}

+ file build/8c9e4bb7edede879310e.woff2 build/a2abc9c944c48139f361.eot build/ea5b4187c7d3276d80ad.woff build/f0f49284f1a83efbf8c2.ttf build/fonts/materialdesignicons-webfont.eot build/fonts/materialdesignicons-webfont.ttf build/fonts/materialdesignicons-webfont.woff build/fonts/materialdesignicons-webfont.woff2
build/8c9e4bb7edede879310e.woff2:              ASCII text, with no line terminators
build/a2abc9c944c48139f361.eot:                ASCII text, with no line terminators
build/ea5b4187c7d3276d80ad.woff:               ASCII text, with no line terminators
build/f0f49284f1a83efbf8c2.ttf:                ASCII text, with no line terminators
build/fonts/materialdesignicons-webfont.eot:   Embedded OpenType (EOT), Material Design Icons family
build/fonts/materialdesignicons-webfont.ttf:   TrueType Font data, 11 tables, 1st "GSUB", 16 names, Macintosh, type 1 string, Material Design IconsRegularMaterial Design IconsMaterial Design IconsVersion 1.0MaterialDesign
build/fonts/materialdesignicons-webfont.woff:  Web Open Font Format, TrueType, length 465188, version 1.0
build/fonts/materialdesignicons-webfont.woff2: Web Open Font Format (Version 2), TrueType, length 325244, version 1.0

When changing the css-loader version in package.json to "webpack-contrib/css-loader#13b7458be2ef0d7a6b334e5e8149d83de6478403" (latest commit on master), you get the following. The links are now working and the files are where I want them to be.

+ head -9 build/css/system.css
/* MaterialDesignIcons.com */
@font-face {
  font-family: "Material Design Icons";
  src: url(/fonts/materialdesignicons-webfont.eot);
  src: url(/fonts/materialdesignicons-webfont.eot?#iefix&v=5.9.55) format("embedded-opentype"), url(/fonts/materialdesignicons-webfont.woff2) format("woff2"), url(/fonts/materialdesignicons-webfont.woff) format("woff"), url(/fonts/materialdesignicons-webfont.ttf) format("truetype");
  font-weight: normal;
  font-style: normal;
}

+ file build/*.* build/fonts/materialdesignicons-webfont.eot build/fonts/materialdesignicons-webfont.ttf build/fonts/materialdesignicons-webfont.woff build/fonts/materialdesignicons-webfont.woff2
build/*.*:                                     cannot open `build/*.*' (No such file or directory)
build/fonts/materialdesignicons-webfont.eot:   Embedded OpenType (EOT), Material Design Icons family
build/fonts/materialdesignicons-webfont.ttf:   TrueType Font data, 11 tables, 1st "GSUB", 16 names, Macintosh, type 1 string, Material Design IconsRegularMaterial Design IconsMaterial Design IconsVersion 1.0MaterialDesign
build/fonts/materialdesignicons-webfont.woff:  Web Open Font Format, TrueType, length 465188, version 1.0
build/fonts/materialdesignicons-webfont.woff2: Web Open Font Format (Version 2), TrueType, length 325244, version 1.0

However, I now discovered that if I remove the file-loader block from webpack.config.js the links match the file output. They aren't placed where I would like them to be placed, though.

+ head -9 build/css/system.css
/* MaterialDesignIcons.com */
@font-face {
  font-family: "Material Design Icons";
  src: url(/53f53f50a1b2033979f5.eot?v=5.9.55);
  src: url(/53f53f50a1b2033979f5.eot?#iefix&v=5.9.55) format("embedded-opentype"), url(/e9db4005489e24809b62.woff2?v=5.9.55) format("woff2"), url(/d8e8e0f7931afa097409.woff?v=5.9.55) format("woff"), url(/0e4e0b3da55fa7faa77b.ttf?v=5.9.55) format("truetype");
  font-weight: normal;
  font-style: normal;
}

+ file build/0e4e0b3da55fa7faa77b.ttf build/53f53f50a1b2033979f5.eot build/d8e8e0f7931afa097409.woff build/e9db4005489e24809b62.woff2 build/fonts/*
build/0e4e0b3da55fa7faa77b.ttf:   TrueType Font data, 11 tables, 1st "GSUB", 16 names, Macintosh, type 1 string, Material Design IconsRegularMaterial Design IconsMaterial Design IconsVersion 1.0MaterialDesign
build/53f53f50a1b2033979f5.eot:   Embedded OpenType (EOT), Material Design Icons family
build/d8e8e0f7931afa097409.woff:  Web Open Font Format, TrueType, length 465188, version 1.0
build/e9db4005489e24809b62.woff2: Web Open Font Format (Version 2), TrueType, length 325244, version 1.0
build/fonts/*:                    cannot open `build/fonts/*' (No such file or directory)

Does this mean that I'm not supposed to use file-loader anymore? In that case, I'll just have to find out how to specify the output directory for the font files with css-loader. :)

@alexander-akait
Copy link
Member

@sjoqvist Can you create github repo better, it is faster - just clone and run npm run build, it is enough for me, and yes you should not use file-loader with webpack v5, anyway it should work without any problems

@alexander-akait
Copy link
Member

You can find more information here https://webpack.js.org/guides/asset-modules/

@sjoqvist
Copy link

@sjoqvist Can you create github repo better, it is faster - just clone and run npm run build, it is enough for me, and yes you should not use file-loader with webpack v5, anyway it should work without any problems

I see, thanks. When upgrading to v5, I read the changelog and migration guide but didn't see file-loader mentioned anywhere, plus I've never seen a deprecation warning. This is why I was surprised when the file export stopped working.

I'll set up a GitHub repo in a bit.

@sjoqvist
Copy link

@alexander-akait
Copy link
Member

Works fine with file-loader:
Screenshot from 2021-05-15 16-05-00
Works fine with asset/resource:
Screenshot from 2021-05-15 16-06-29

@alexander-akait
Copy link
Member

You can set filename for type: "asset/resource" using these approaches https://webpack.js.org/guides/asset-modules/#custom-output-filename

@alexander-akait
Copy link
Member

alexander-akait commented May 15, 2021

Can you provide steps to get the problem? Maybe you have wrong configured server?

@sjoqvist
Copy link

You can set filename for type: "asset/resource" using these approaches https://webpack.js.org/guides/asset-modules/#custom-output-filename

Thanks. I've already fixed it in my own project. I thought that file-loader should still work, even if it's deprecated. If it's not supported anymore and is allowed to fail, then feel free to drop this completely.

I'm not sure what I'm looking at. Your screenshots don't look like the output from my demo. Did you try my demo repository? It should include all the steps. Just run /build.sh and then ./run.sh.

@alexander-akait
Copy link
Member

@sjoqvist

I'm not sure what I'm looking at. Your screenshots don't look like the output from my demo. Did you try my demo repository? It should include all the steps. Just run /build.sh and then ./run.sh.

Yes, and these screenshots from there with file-loader and type: "asset/resource". Can you provide screenshot of the problem

@sjoqvist
Copy link

sjoqvist commented May 21, 2021

@alexander-akait

Yes, and these screenshots from there with file-loader and type: "asset/resource". Can you provide screenshot of the problem

My apologies for not responding sooner. I haven't been able to figure out what you need.

Just to be clear: Getting rid of file-loader solved my problem, but I'm happy to help out with debugging if you could use the help. But the demo repository that I set up includes everything to reproduce the problem. It does not, however, include everything needed to serve a website. If you want a screenshot of a browser, I'll need to set up a new repository or change the one I created considerably.

The screenshots that you provided aren't from anything served by my repository. Hence, those screenshots don't tell me anything.

I think that there's some kind of misunderstanding. A screenshot of a browser that says "Failed to decode downloaded font" seems utterly useless.

  1. Do you agree that if css-loader outputs CSS that points to JS files instead of font files, then the browser interprets the files as corrupt?
  2. Did you get my demo to work?
  3. Did you understand what its output means? The output is meant to provide everything you need to understand the problem (which a screenshot wouldn't).
  4. Do you need a screenshot that shows that my browser (Chrome) complains that the font files don't have the correct format, or do you want screenshots of something else?

@alexander-akait alexander-akait merged commit 7ec5831 into master Jul 14, 2021
@alexander-akait alexander-akait deleted the next branch April 8, 2023 18:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants