Skip to content
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

filename ending with query will not be injected, e.g. "[name].[hash].css?for-print" #1367

Closed
liby opened this issue Mar 25, 2020 · 6 comments

Comments

@liby
Copy link

liby commented Mar 25, 2020

Expected behaviour

In HtmlWebpackPlugin v3.2, the CSS files that affect the global are injected correctly here, and the page is displayed normally.

Expected behaviour

Current behaviour

After upgrading to v4.0, there should be a <link> tag between them to introduce the CSS file exported by the MiniCssExtractPlugin, but it wasn't injected, so the display of all pages has no style.

Current behaviour

Environment

Node.js: v13.3.0
darwin: 19.2.0
npm: 6.13.1

npm ls webpack:
demo@1.0.0 /Volumes/Code/web
├─┬ @storybook/react@5.3.17
│ ├─┬ @storybook/core@5.3.17
│ │ ├─┬ corejs-upgrade-webpack-plugin@2.2.0
│ │ │ └── webpack@4.41.2
│ │ └── webpack@4.41.2
│ └── webpack@4.41.2
└── webpack@4.42.0

npm ls html-webpack-plugin: 
demo@1.0.0 /Volumes/Code/web
├─┬ @storybook/react@5.3.17
│ └─┬ @storybook/core@5.3.17
│   └── html-webpack-plugin@4.0.0-beta.11
└── html-webpack-plugin@3.2.0

Config

  • webpack.common.js
const path = require("path");
const webpack = require("webpack");
const { projectRoot, distPath, srcPath, entryName } = require("./constants");
const entryPointMapping = require("./entrypoint-mapping");
const getClientEnvironment = require("./env");
// Import all rules
const fileRule = require("./rules/file.rule");
const lessRule = require("./rules/less.rule")({
  sourceMap: true,
  preserveUrl: false
});
const sassRule = require("./rules/sass.rule");
const pugTemplateRule = require("./rules/pug-template.rule");
const pugRule = require("./rules/pug.rule");
const typescriptRule = require("./rules/typescript.rule");
// import all plugin
const cssExtractPlugin = require("./plugins/css-extract.plugin");
const {
  advisorHtmlPlugin: advisorHtml
} = require("./plugins/html.puglin");
const tsconfigPathsWebpackPlugin = require("./plugins/tsconfig-paths-webpack.plugin");

const env = getClientEnvironment("/");

module.exports = {
  target: "web",
  entry: entryPointMapping,
  output: {
    path: distPath,
    filename: "assets/[name].[hash].js"
  },
  resolve: {
    extensions: [".ts", ".tsx", ".js", ".json", ".svg", ".less", "scss"],
    alias: {},
    modules: [srcPath, path.resolve(projectRoot, "node_modules")],
    plugins: [tsconfigPathsWebpackPlugin]
  },
  module: {
    rules: [
      fileRule,
      lessRule,
      sassRule,
      {
        test: /\.pug$/,
        oneOf: [pugTemplateRule, pugRule]
      },
      typescriptRule
    ]
  },
  plugins: [
    advisorHtml,
    cssExtractPlugin
  ]
};
  • entrypoint-mapping.js
const path = require("path");
const { projectRoot, entryName } = require("./constants");

// Add all to mapping
const entrypointMapping = {};
entrypointMapping[entryName.advisor] = path.resolve(
  projectRoot,
  "src/application/advisor/index.ts"
);

entrypointMapping[entryName.advisorTemplates] = path.resolve(
  projectRoot,
  "src/application/advisor/templates.ts"
);

module.exports = entrypointMapping;
  • constants.js
const path = require("path");

const projectRoot = path.resolve(__dirname, "../..");
const distPath = path.resolve(projectRoot, "dist");
const srcPath = path.resolve(projectRoot, "src");
const devMode = process.env.NODE_ENV !== "production";

const entryName = {
  advisor: "advisor",
  advisorTemplates: "advisor-templates",
};

module.exports = {
  projectRoot,
  distPath,
  srcPath,
  entryName
};
  • css-extract.plugin.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = new MiniCssExtractPlugin({
  filename: "assets/[name].[hash].css?for-print"
});
  • html.puglin.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { projectRoot, srcPath } = require("../constants");

module.exports.advisorHtmlPlugin = new HtmlWebpackPlugin({
  filename: "advisor/index.html",
  template: path.resolve(srcPath, "application/advisor/index.pug"),
  title: "demo",
  inject: true,
  chunks: ["advisor-templates", "advisor"],
  chunksSortMode: "manual",
  metadata: {
    cdnFiles: require(path.resolve(
      projectRoot,
      "scripts",
      "config",
      "cdn-files.json"
    ))
  }
});
  • _mixin-cdn.pug
- var root = 'https://cdnjs.cloudflare.com/ajax/libs/'
- var metadata = locals.htmlWebpackPlugin.options.metadata
- var cdnFiles = metadata.cdnFiles

mixin cdnJs(type)
  each file in cdnFiles[type]
    if file.match(/\.(\w+)$/)[1] === 'js'
      script(src=`${root}${file}`)

mixin cdnCss(type)
  each file in cdnFiles[type]
    if file.match(/\.(\w+)$/)[1] === 'css'
      link.for-print(rel='stylesheet', href=`${root}${file}`)
  • _layout.pug
doctype html
include ./_mixin-cdn

html#ng-app(lang='en')

  head
    block pug-config
    meta.for-print(charset='utf-8')
    meta(http-equiv='X-UA-Compatible' content='IE=Edge')
    title(ng-bind='metatags.title')
    meta(name='viewport' content='width=1250')
    link(rel='canonical' ng-href='{{metatags.canonical}}')
    link(rel='prefetch' href='@{static_url_base}font/example.woff?-7wb623' as='font' type='application/x-font-woff' pr='1')
    link(rel='prefetch' href='@{static_url_base}font/glyphicons-halflings-regular.woff' as='font' type='application/x-font-woff' pr='0.1')

    block styles
      // ...
      +cdnCss("shared")
      +cdnCss("private")
      link.for-print(rel='stylesheet' href='https://fast.fonts.net/cssapi/601fe215-1fea-4ab3-80c3-fd766918bece.css')
      style
        | [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak { display: none !important; }
  body
  // ...

Relevant Links

  • No yet

Additional context

Similar to #1346, his description is not accurate enough, it has little to do with [hash], but he did say why:

UPD #⁠2: It seems that it doesn't work if I even add empty query (i.e. [name].css?)

That's the point, After version 4.0, files with filenames ending in ?xxx will not be injected, even if it is an empty query.

@jantimon
Copy link
Owner

jantimon commented Mar 25, 2020

That is correct - question marks are not valid for file names on the disk

it seems like the question mark is now escaped by webpack.

why do you want to have question marks in filenames?

@jantimon
Copy link
Owner

What do you mean by that?

@foyzhao
Copy link

foyzhao commented Mar 30, 2020

Question marks were supported in html-webpack-plugin@3.2.0 but not in html-webpack-plugin@4.0.3

output: {
  filename: 'assets/name.js?whatever'
},
plugins: [
  new MiniCssExtractPlugin({
    filename: 'assets/name.css?whatever'
  }),
]

@jantimon
Copy link
Owner

same as

#1346
#1355
#1374

@jantimon
Copy link
Owner

I have reported this issue here: webpack/webpack#10638

@jantimon
Copy link
Owner

I will try to bring back the same behaviour as in 3.2 for details please see #1355

Repository owner deleted a comment from liby Mar 31, 2020
@lock lock bot locked as resolved and limited conversation to collaborators May 5, 2020
Repository owner unlocked this conversation Feb 15, 2023
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

No branches or pull requests

3 participants