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

"Passing individual values" config output errors #11

Closed
florent-cdl opened this issue Dec 10, 2021 · 21 comments · Fixed by #15
Closed

"Passing individual values" config output errors #11

florent-cdl opened this issue Dec 10, 2021 · 21 comments · Fixed by #15

Comments

@florent-cdl
Copy link

Hi,
I'm trying to get the current filename inside my ejs template (which include an ejs with that name) but can't get that parameter either by HtmlWebpackPlugin options or template-ejs-loader.

This is a part of my webpack.config (plugins part, sorry some quotes don't render ,so have to change "`" to "'") :

...arrayOfEntry.map( (page) => new HtmlWebpackPlugin({ inject: true, template: '${projectPaths.projectEjsTemplatesPath}/webpack-base-standard.ejs', filename: '../${page}.html', chunks: [page, "common"], templateParameters: { env: process.env.NODE_ENV, jsPath: projectPaths.projectJsPath, cssPath: projectPaths.projectScssPath, ejsPath: projectPaths.projectEjsPath, filename: page }, }) ),

filename templateParameters always set to the first 'page' var opf the loop
I've tried (as specified in readme file)

template: '!${require.resolve('html-loader')}??ruleSet[1].rules[0].use[0]!${path.resolve( __dirname, '../lib/index.js' )}?${new URLSearchParams({ // Use the query as an option to pass to the loader root: projectPaths.projectEjsTemplatesPath, data: JSON.stringify({ foo: 'bar', }), })}!${projectPaths.projectEjsTemplatesPath}/webpack-base-standard.ejs',

but get the error
ERROR in Error: Child compilation failed: Module not found: Error: Can't resolve '/Volumes/TEST-WEBPACK/lib/index.js' in '/Volumes/TEST-WEBPACK'

Please if someone get the solution. What I'm trying to get inside the template ejs

<%- include('${htmlWebpackPlugin.options.ejsPath}/${htmlWebpackPlugin.options.filename}.ejs', {myvar : 'test'}) %>

Best regards
Florent

@dc7290
Copy link
Owner

dc7290 commented Dec 10, 2021

@florent-cdl

Hello.
Thank you for using our library here!

Could you please create a sample project to reproduce the error?
Or please attach webpack.config.js.

We might be able to figure out if the error is caused by html-webpack-plugin, template-ejs-loader, or something else.
or something else.

@florent-cdl
Copy link
Author

Hi,

What I want to do is :

  • have a loader that understand "include"
  • get the current filename var inside the .ejs to include the right .ejs file (code of my ejs template : <%- include(${htmlWebpackPlugin.options.ejsPath}/${htmlWebpackPlugin.options.filename}.ejs, {components : owInclude}) %>)

I managed to get that filename but was obliged to modify your loader : I've added that line (after line 70 of node_modules/template-ejs-loader/lib/index.js )
filename: Object.keys(this._compiler?.options.entry)[0]
but can't keep such a solution that will be erase in update

My webpack.config.js is quite long but here is (at the message bottom) a brief view.

I just resumed entries with 2 lines but this part is a loop on multiple files like the HTMLWebpackPlugin part.

Your loader doesn't allow templateParameters as a function (but not sure it is the solution)

A more simple HTMLWebpackPlugin version I test never give me the right filename but always the first one used on the loop (event if filename is the right one in the loop below)

new HtmlWebpackPlugin({ inject: true, template:${projectPaths.projectEjsTemplatesPath}/webpack-base-standard.ejs, filename: ../${page}.html, chunks: [page, "common"], templateParameters: { env: process.env.NODE_ENV, jsPath: projectPaths.projectJsPath, cssPath: projectPaths.projectScssPath, ejsPath: projectPaths.projectEjsPath, filename: page }, })

So I tested this one to have singular parameter :

new HtmlWebpackPlugin({ inject: true, // template:${projectPaths.projectEjsTemplatesPath}/webpack-base-standard.ejs, template: !${require.resolve('html-loader')}??ruleSet[1].rules[0].use[0]!${path.resolve(
__dirname,
'../node_modules/template-ejs-loader/lib/index.js'
)}?${new URLSearchParams({
// Use the query as an option to pass to the loader
root: projectPaths.projectOutput,
data: JSON.stringify({
filename: page
}),
})}!${projectPaths.projectEjsTemplatesPath}/webpack-base-standard.ejs, filename: ../${page}.html, chunks: [page, "common"], templateParameters: { env: process.env.NODE_ENV, jsPath: projectPaths.projectJsPath, cssPath: projectPaths.projectScssPath, ejsPath: projectPaths.projectEjsPath, filename: page }, })

{ mode: 'development', devServer: { static: { directory: '/Volumes/TRAVAUX/PROJETS/TEST-WEBPACK/dist' } }, entry: { 'about-us': '/Volumes/TRAVAUX/PROJETS/TEST-WEBPACK/src/bundles/js/about-us.js', 'account-credit-card-create': '/Volumes/TRAVAUX/PROJETS/TEST-WEBPACK/src/bundles/js/account-credit-card-create.js' }, output: { chunkFilename: '[id].chunk.js', path: '/Volumes/TRAVAUX/PROJETS/TEST-WEBPACK/dist/js', assetModuleFilename: 'images/[hash][ext][query]', filename: '[name]-modern.js' }, resolve: { extensions: [ '*', '.js', '.jsx' ], alias: { handlebars: 'handlebars/dist/handlebars.js' }, modules: [ '/Volumes/TRAVAUX/PROJETS/TEST-WEBPACK/node_modules' ] }, devtool: false, module: { rules: [ { test: /\.ejs$/, use: [ { loader: 'html-loader', options: { // Disables attributes processing sources: false, }, }, { loader: 'template-ejs-loader', options: {data: {test:'true'}} } ], } ] }, name: 'client-modern', target: 'browserslist:modern',

@florent-cdl
Copy link
Author

Hi,
do you find some resolutions ? or ways to have the filename parameters inside the ejs ?

Thank you

@florent-cdl
Copy link
Author

Hi,
I'm interested having your knowledge on that point because i'm really stopped and can't find a solution right now
Thank you

@mizok
Copy link
Contributor

mizok commented Jan 9, 2022

@florent-cdl
Uh.. I guess you need to describe your question more clearly, since you are not able to give a reproducible repository.
(bc even me don't understand what the problem is...)

And if you want to show your .js code, you can use

img

@florent-cdl
Copy link
Author

Hi,
It's very simple :
How can I get the current filename inside my ejs template ? As I want to include an ejs which has the same name as the filename being process (but in another template part directory)
Thank you

@mizok
Copy link
Contributor

mizok commented Jan 9, 2022

@florent-cdl

You mean ... just like this?

folder structure:

root
├── index.ejs
├── partials1
               └──── tempA.ejs
└── partials2
               └──── tempA.ejs

index.ejs:

<%- include "./partials1/tempA.ejs" %>
<%- include "./partials2/tempB.ejs" %>

@mizok
Copy link
Contributor

mizok commented Jan 9, 2022

I guess I know what you are meaning about.
You got all your htmlWebpackPlugin instances generated within a loop, and you want to get current filename(when iterated) inside your .ejs template as a variable right?
(But this seems to be a weird using condition, at least it is to me 😐 )

@florent-cdl
Copy link
Author

This is exactly the pb.
We have a complex site with lot of ejs files and includes
So do you know how to get that value ?

@mizok
Copy link
Contributor

mizok commented Jan 10, 2022

@florent-cdl

I don't think there is an existing way(using this loader) for your problem.
And I am not sure if @dc7290 is busy by this time :( (It's Asian new year time now.)
I did try to contact him using twitter, but no luck.

Even I get a solution, I still have to wait for the reviewing of my pull request.
(I also had my pull request commited, but still not get contacted.)

Actually I am thinking about creating a new ejs loder npm package on my own BTW :/

@florent-cdl
Copy link
Author

Great ! Thank you very much
I will wait your message
Have a nice day

@mizok
Copy link
Contributor

mizok commented Jan 13, 2022

@florent-cdl

I think I got a temporary solution for you, but not with this loader.
You can try ejs-loader as an alternative.(I have already tested this in my Webapck 5 template repo.)
then you can just use the option templateParameters of htmlWebpackPlugin like below:

new HtmlWebpackPlugin({
    filename: ...,
    template: ...,
    templateParameters:{
      filename://  filename you get.
    }
    
  })

And in .ejs file:

<!DOCTYPE html>
<html lang="en">

<head></head>

<body>
  <div class="site">
    <div class="site__header-wrapper">

    </div>
    <div class="site__body">
      <!-- use temaplateParameter-->
      <h1><%= htmlWebpackPlugin.options.filename %></h1>
    </div>
    <div class="site__footer-wrapper">
       <!-- include other partial-->
      <%= require('./src/template/footer.ejs')() %>
      <!-- no using alias -->
      <img src="./assets/images/xxx.png">
    </div>
  </div>

</body>

</html>

PS.But if you decide to use ejs-loader, you will have to give up using html-loader(bc they conflict), which means your webpack ejs module rule will become like this:

{
        test: /\.ejs$/,
        use: [// no other loader except ejs-loader
          {
            loader: 'ejs-loader',
            options: {
              esModule:false
            }
          }
        ]
      },

And ONCE you remove html-loader, it means:

  • Webpack will no longer detect your image source loaded using img tag in ejs files.
  • You can't use source alias in .ejs files anymore.
  • You will need a webpack-copy-plugin to copy all your image assets to your dist folder, and Webpack will not do the tree shaking for images which is not used in project.

Just feel free to ask if you have any problem about this solution :D.

@florent-cdl
Copy link
Author

Hi
Thank you for the solution
I've already tried lot of ejs loaders, and this one.
I can't remember the pb with this one but I will give it a try and get back to you.
And otherwise, the evoution I give in my previous messages ? :
_I managed to get that filename but was obliged to modify your loader : I've added that line (after line 70 of node_modules/template-ejs-loader/lib/index.js )
filename: Object.keys(this.compiler?.options.entry)[0]
but can't keep such a solution that will be erase in update

Best regards

@mizok
Copy link
Contributor

mizok commented Jan 13, 2022

It's not "my loader"... pal lol.
I am just another user trying to fix things up haha.

If you do have some good idea about fixing this issue, I suggest you just make a pull request.
And once your pull request get accepted, your modification will get merge into this package, and it won't be erased again even you do npm install.

But about the message you mentioned above, I don't think that's a good way to go, 'cause not everyone using this loader will need that filename variable, so it may not be accepted by the author if you make this as a pull request I guess.

@dc7290
Copy link
Owner

dc7290 commented Jan 15, 2022

@mizok
Thank you for offering a solution on my behalf.

@florent-cdl
Copy link
Author

Hi d-suke,
What do you think of the solution I give, :
adding this line (after line 70 of node_modules/template-ejs-loader/lib/index.js ) :
filename: Object.keys(this.compiler?.options.entry)[0]
Or perhaps you have another solution ?
Thank you

@dc7290
Copy link
Owner

dc7290 commented Jan 15, 2022

@florent-cdl

Sorry for the late reply.

I still do not understand the problem you are having.
Are you saying that you want to pass different values to each ejs file?

@florent-cdl
Copy link
Author

I just want to get the current filenmane as a variable inside the ejs.
I've tried the way with "queryString.stringify" but without success (as you can see in my first message)
My webpack file is quite complex, htmlwebbpack inside a loop.
No way to get that filename and use it inside the ejs template

@mizok
Copy link
Contributor

mizok commented Jan 15, 2022

@dc7290
I just made another pull request for you about this issue.
you can check it.

@mizok
Copy link
Contributor

mizok commented Jan 15, 2022

@florent-cdl
You can now update to v.0.7.0 for this issue.(And you can check README.md for the solution)
Though the new solution is not using your idea, I fixed the old method, bc I confirmed that there was something wrong about the entry path, and obviously we need an upgrade for the URLsearchParams issue.
I have already tested this change in my product repository, and it worked fine.

If you still have any problem, just feel free to report a new issue.

@florent-cdl
Copy link
Author

Very nice, you're the best :)
I will give it a try tomorrow.
Best regards

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 a pull request may close this issue.

3 participants