Open beeryukov opened 4 years ago
Can you provide your loader rule from webpack config?
I also have this issue, I can resolve it by setting var query = {};
My loader rule is below.
{
test: /\.ejs$/,
use: {
loader: 'ejs-compiled-loader',
options: {
htmlmin: true,
htmlminOptions: {
removeComments: true
}
}
}
}
Here are my dev dependencies
"@types/node": "^13.13.4",
"copy-webpack-plugin": "^5.1.1",
"css-loader": "^3.5.3",
"ejs-compiled-loader": "^3.0.0",
"eslint": "^6.8.0",
"file-loader": "^6.0.0",
"html-webpack-plugin": "^4.2.0",
"image-webpack-loader": "^6.0.0",
"mini-css-extract-plugin": "^0.9.0",
"style-loader": "^1.2.0",
"ts-loader": "^7.0.1",
"typescript": "^3.8.3",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.10.3"
@beeryukov, I believe I resolved this for myself.
I was using the HtmlWebpackPlugin like this:
new HtmlWebpackPlugin({
template: "!!ejs-compiled-loader!./public/index.ejs",
templateParameters: {
posts: postTemplates,
post: false
}
}),
However, you can also just set the loader as a rule in your loader, HtmlWebpackPlugin will pick up this rule. So you can change the Html Webpack Plugin to not use the !!ejs-compiled-loader!
syntax
{
test: /\.ejs$/,
use: {
loader: 'ejs-compiled-loader',
options: {
htmlmin: true,
htmlminOptions: {
removeComments: true
}
}
}
}
&
new HtmlWebpackPlugin({
template: "./public/index.ejs",
templateParameters: {
posts: postTemplates,
post: false
}
}),
Kind of confusing between the READMEs, but solved my issue.
I also had this issue, I resolved it by changing my webpack rule from:
rules: [
{
test: /\.ejs$/,
use: 'ejs-compiled-loader'
}]
to:
rules: [
{
test: /\.ejs$/,
use: {
loader: 'ejs-compiled-loader',
options: {
htmlmin: true,
htmlminOptions: {
removeComments: true
}
}
}
}]
It seems ejs-compiled-loader does not like options
being undefined.
I also had this issue, but It can't be solved by the above method, So someone can help me, thank you.
I also had this issue, but It can't be solved by the above method, So someone can help me, thank you.
Can you share your ejs webpack config rule?
I also had this issue, but It can't be solved by the above method, So someone can help me, thank you.
Can you share your ejs webpack config rule? webpack.config.js
const path = require('path'); const webpack = require('webpack') const HtmlWebpackPlugin = require('html-webpack-plugin'); const MinCssExtractPlugin = require("mini-css-extract-plugin"); // 将css代码提取为独立文件的插件 const MediaQueryPlugin = require('media-query-plugin');
module.exports = { mode: 'production', entry: [ './src/index.js' ], output: { path: path.resolve(dirname, './dist'), filename: 'bundle.js' }, module: { rules: [{ test: /.s[ac]ss$/i, use: [ { loader: MinCssExtractPlugin.loader, // 将处理后的CSS代码提取为独立的CSS文件,可以只在生产环境中配置,但我喜欢保持开发环境与生产环境尽量一致 options: { publicPath: '/assets/', // only enable hot in development hmr: true, // if hmr does not work, this is a forceful method. reloadAll: true, }, }, 'css-loader', // CSS加载器,使webpack可以识别css文件 MediaQueryPlugin.loader, 'postcss-loader', // 承载autoprefixer功能,为css添加前缀 'sass-loader', // Compiles Sass to CSS ], }, { test: /.css$/, use: [{ loader: 'file-loader', options: { name: '[name].[hash:8].[ext]', outputPath: 'assets/', publicPath: './assets/' } }, 'extract-loader', 'css-loader', 'postcss-loader'] }, { test: /.(jpg|png|gif|svg)$/, use: { loader: 'file-loader', options: { name: '[name].[hash:8].[ext]', outputPath: 'assets/', publicPath: './assets/' } } }, { test: /.ejs$/, use: { loader: 'ejs-compiled-loader', options: { htmlmin: true, htmlminOptions: { removeComments: true } } } } ] }, plugins: [new HtmlWebpackPlugin({ template: 'src/index.ejs', inject: true, minify: { collapseWhitespace: true } }), new webpack.HotModuleReplacementPlugin(), new MinCssExtractPlugin(), new MediaQueryPlugin({ include: [ 'style', ], queries: { 'print': 'print', 'not print': 'not-print' } }) ], devServer: { contentBase: path.join(dirname, 'dist'), compress: true, overlay: true, port: 4550, open: true, hot: true } };
package.json
```javascript
{
"name": "resume",
"version": "1.0.0",
"description": "个人简历",
"main": "index.js",
"repository": "",
"author": "",
"license": "MIT",
"scripts": {
"start": "webpack-dev-server --mode=development",
"build": "webpack --mode=production"
},
"devDependencies": {
"@babel/core": "^7.10.2",
"@babel/preset-env": "^7.10.2",
"autoprefixer": "^9.1.5",
"babel-loader": "^8.1.0",
"css-loader": "^1.0.0",
"cssnano": "^4.1.0",
"ejs-compiled-loader": "^3.0.0",
"ejs-loader": "^0.5.0",
"extract-loader": "^2.0.1",
"file-loader": "^1.1.11",
"html-webpack-plugin": "^3.2.0",
"media-query-plugin": "^1.3.1",
"mini-css-extract-plugin": "^0.9.0",
"node-sass": "^4.14.1",
"postcss-import": "^12.0.1",
"postcss-loader": "^3.0.0",
"postcss-px2rem-exclude": "0.0.6",
"postcss-url": "^8.0.0",
"px2rem-loader": "^0.1.9",
"raw-loader": "^0.5.1",
"sass-loader": "^8.0.2",
"style-loader": "^1.2.1",
"webpack": "^4.43.0",
"webpack-cli": "^3.1.0",
"webpack-dev-server": "^3.11.0"
},
"dependencies": {
"fs": "0.0.1-security",
"lib-flexible": "^0.3.2"
}
}
I also had this issue, but It can't be solved by the above method, So someone can help me, thank you.
Can you share your ejs webpack config rule? webpack.config.js
const path = require('path'); const webpack = require('webpack') const HtmlWebpackPlugin = require('html-webpack-plugin'); const MinCssExtractPlugin = require("mini-css-extract-plugin"); // 将css代码提取为独立文件的插件 const MediaQueryPlugin = require('media-query-plugin'); module.exports = { mode: 'production', entry: [ './src/index.js' ], output: { path: path.resolve(__dirname, './dist'), filename: 'bundle.js' }, module: { rules: [{ test: /\.s[ac]ss$/i, use: [ { loader: MinCssExtractPlugin.loader, // 将处理后的CSS代码提取为独立的CSS文件,可以只在生产环境中配置,但我喜欢保持开发环境与生产环境尽量一致 options: { publicPath: '/assets/', // only enable hot in development hmr: true, // if hmr does not work, this is a forceful method. reloadAll: true, }, }, 'css-loader', // CSS加载器,使webpack可以识别css文件 MediaQueryPlugin.loader, 'postcss-loader', // 承载autoprefixer功能,为css添加前缀 'sass-loader', // Compiles Sass to CSS ], }, { test: /\.css$/, use: [{ loader: 'file-loader', options: { name: '[name].[hash:8].[ext]', outputPath: 'assets/', publicPath: './assets/' } }, 'extract-loader', 'css-loader', 'postcss-loader'] }, { test: /\.(jpg|png|gif|svg)$/, use: { loader: 'file-loader', options: { name: '[name].[hash:8].[ext]', outputPath: 'assets/', publicPath: './assets/' } } }, { test: /\.ejs$/, use: { loader: 'ejs-compiled-loader', options: { htmlmin: true, htmlminOptions: { removeComments: true } } } } ] }, plugins: [new HtmlWebpackPlugin({ template: 'src/index.ejs', inject: true, minify: { collapseWhitespace: true } }), new webpack.HotModuleReplacementPlugin(), new MinCssExtractPlugin(), new MediaQueryPlugin({ include: [ 'style', ], queries: { 'print': 'print', 'not print': 'not-print' } }) ], devServer: { contentBase: path.join(__dirname, 'dist'), compress: true, overlay: true, port: 4550, open: true, hot: true } };
package.json
{ "name": "resume", "version": "1.0.0", "description": "个人简历", "main": "index.js", "repository": "", "author": "", "license": "MIT", "scripts": { "start": "webpack-dev-server --mode=development", "build": "webpack --mode=production" }, "devDependencies": { "@babel/core": "^7.10.2", "@babel/preset-env": "^7.10.2", "autoprefixer": "^9.1.5", "babel-loader": "^8.1.0", "css-loader": "^1.0.0", "cssnano": "^4.1.0", "ejs-compiled-loader": "^3.0.0", "ejs-loader": "^0.5.0", "extract-loader": "^2.0.1", "file-loader": "^1.1.11", "html-webpack-plugin": "^3.2.0", "media-query-plugin": "^1.3.1", "mini-css-extract-plugin": "^0.9.0", "node-sass": "^4.14.1", "postcss-import": "^12.0.1", "postcss-loader": "^3.0.0", "postcss-px2rem-exclude": "0.0.6", "postcss-url": "^8.0.0", "px2rem-loader": "^0.1.9", "raw-loader": "^0.5.1", "sass-loader": "^8.0.2", "style-loader": "^1.2.1", "webpack": "^4.43.0", "webpack-cli": "^3.1.0", "webpack-dev-server": "^3.11.0" }, "dependencies": { "fs": "0.0.1-security", "lib-flexible": "^0.3.2" } }
I solved this problem in other ways, This link
index.ejs:
<h1><%- require('./header.ejs')({ title: 'page name' }) -%></h1>
header.ejs:
<title><%= title %></title>
It's a bug, this.query is blindly passed to utils.parseQuery() which throws the error "A valid query string passed to parseQuery should begin with '?'" if the string representation of that object does not start with a '?'. See https://github.com/bazilio91/ejs-compiled-loader/blob/3.x/index.js#L15
Steps to reproduce: Import without options object or query: '!!ejs-compiled-loader!./path/to/template' yields this error. Import with an undefined query: '!!ejs-compiled-loader?!./path/to/template' yields this error. Import with an empty object: '!!ejs-compiled-loader?{}!./path/to/template' yields no errors.
Debugging: I used this code inserted before https://github.com/bazilio91/ejs-compiled-loader/blob/3.x/index.js#L15
console.log("this.query is set");
console.log("this.query is of type " + typeof this.query);
if(typeof this.query === 'object') console.log("query is an 'object'");
else console.log("query is not an 'object'");
}
else {
console.log("no query");
}
The output of that is
for !!ejs-compiled-loader!./path/to/tpl
as well as !!ejs-compiled-loader?!./path/to/tpl
this.query is set
this.query is of type string
and for !!ejs-compiled-loader?{}!./path/to/tpl
:
this.query is set
this.query is of type string
?{}
As such, loader-utils.parseQuery
will throw that error if neither options nor a query is supplied. See https://github.com/webpack/loader-utils/blob/c937e8c77231b42018be616b784a6b45eac86f8a/lib/parseQuery.js#L11 for the parseQuery() code.
Note that the webpack loaders API documentation omits that this.query
is set to an empty string if the query is "undefined". If that didn't happen, at least !!loader?!./path/to/tpl
would work correctly.
However, there is a shorthand to checking for an options object or passing the query to loader-utils.parseQuery()
documented right below: https://webpack.js.org/api/loaders/#thisgetoptionsschema
Using this getOptions()
would replace both Lines 12 and 15 in index.js, I assume.
OffTopic: To be honest, webpack is already at version 5 (beta) and this loader does some v4 stuff incorrectly in a branch called 3.x... I'm ditching this loader and giving that whole "do everything through webpack" a thorough reconsideration. There's an awful lot of dependencies that could break at any given moment (like this one). It was fun to learn this new-fangled webdev stuff, but I don't think I need that for my personal projects.
Thanks for playing.
I'm also seeing this happen, and it definitely wasn't happening before. Using that weird !!ejs-compiled-loader?{}!
prefix syntax fixed it for me, but that's just awful. My loader is pretty basic, and I'm not using this alongside HtmlWebpackPlugin
, just a Webpacker app with Rails.
ejs-compiled-loader version is 3.0.0 "webpack" is "4.43.0", "webpack-cli" is "3.3.11" Get the following error when building: