Hello,
Here I try to import and use an image in a react component, but this one is never found :
GET http://localhost:8000/[object%20Module] 404 (Not Found)
I try to access to defaultLogo.png which is in this tree:
https://prnt.sc/s92g2r
Here is my part of the code which is supposed to call and use it:
const pathToLogo = require('../../images/user_logo/${userData.logo_name}');
<img src={pathToLogo} alt=""/>
And here's my webpack encore config :
var Encore = require('@symfony/webpack-encore');
if (!Encore.isRuntimeEnvironmentConfigured()) {
Encore.configureRuntimeEnvironment(process.env.NODE_ENV || 'dev');
}
Encore
.setOutputPath('public/build/')
.setPublicPath('/build')
.addEntry('app', './assets/js/app.jsx')
.splitEntryChunks()
.enableSingleRuntimeChunk()
.cleanupOutputBeforeBuild()
.enableBuildNotifications()
.enableSourceMaps(!Encore.isProduction())
.enableVersioning(Encore.isProduction())
.configureBabelPresetEnv((config) => {
config.useBuiltIns = 'usage';
config.corejs = 3;
})
.enableSassLoader()
.enableReactPreset()
.copyFiles({
from: './assets/images/',
to: 'images/[path][name].[hash:8].[ext]',
pattern: /\.(png|jpg|jpeg|svg)$/
})
;
module.exports = Encore.getWebpackConfig();
Knowing that I'm working with "dev-server", but even "dev" or "build" doesn't work...
Any ideas? Do I misunderstand the syntax? I confess I have some trouble with Webpack encore...
Thanks a lot
Hi,
I think the issue come from the file-loader where your require('...') is now seen as an ES module.
The issue happens because file-loader has been upgraded from v1 to v6 in #731 and released in Encore v0.29.0:
esModules (default false) has been added in file-loader v4.3.0 esModule and is now true by defaultFor now you have two solutions:
require('../../images/user_logo/${userData.logo_name}').defaultesModule like this (I haven't tested it locally, but it should works):Encore
// if you want to keep using `file-loader`
.configureLoaderRule('images', rule => {
rule.options.esModule = false;
})
// OR if you want to use `url-loader`
.configureUrlLoader({
images: {
esModule: false
}
});
However, I think we should configure esModule: false in Encore by defaut, we broke some builds, even if in the Encore 0.29.0 changelog it says:
Unless you're doing custom configuration, it's unlikely you're affected
馃槄
What do you think @Lyrkan?
@Kocal It works by adding .default to the require!
Thanks for the explanations, I admit it's one of the first projects I use webpack encore and I'm having a little trouble ^^'
Thank you very much!
However, I think we should configure esModule: true in Encore by defaut, we broke some builds
Hm, yeah that could be an issue.
But since Webpack seems to be moving everything to ES modules instead of CommonJS (for good reasons) it's probably better to encourage the same thing and keep the default esModule: true.
There is a third "solution" to this issue : use ES imports instead of require(...) (I think that should be changed in our doc as well... people tend to think they are interchangeable but that's not the case):
// Simple imports - needs to be at the top of your module
import '../images/foo.png' as fooPath;
// Dynamic import
// Edit: Note that it will create an async chunk by default which only
// contains the path. If that's an issue it can be fixed relatively
// easily using the `/* webpackMode: "eager" */ comment or through the
// MinChunkSizePlugin.
import('../images/foo.png').then(({ default: fooPath }) => {
// use fooPath there
});
// Dynamic import if you can use async functions
const { default: fooPath } = await import('../images/foo.png');
in the Encore 0.29.0 changelog it says:
Unless you're doing custom configuration, it's unlikely you're affected
Maybe we could change that to something along the lines of:
If you are importing images/fonts using the CommonJS syntax (
require('foo.png')), you will now need to explicitely retrieve the default export (require('foo.png').default) in order to get the path of the file.
Imports done using theimportkeyword should not be affected.
(ping @weaverryan)
Edit: actually using dynamic imports would also require .default... but that was already the case before.
I vote for updating the changelog and keeping the default esModule: true
Most helpful comment
Hi,
I think the issue come from the
file-loaderwhere yourrequire('...')is now seen as an ES module.The issue happens because
file-loaderhas been upgraded from v1 to v6 in #731 and released in Encore v0.29.0:esModules(defaultfalse) has been added in file-loader v4.3.0esModuleand is nowtrueby defaultFor now you have two solutions:
require('../../images/user_logo/${userData.logo_name}').defaultesModulelike this (I haven't tested it locally, but it should works):However, I think we should configure
esModule: falsein Encore by defaut, we broke some builds, even if in the Encore 0.29.0 changelog it says:馃槄
What do you think @Lyrkan?