I am attempting to use the exports-loader with my webpack config, but I'm running into an issue when trying to configure it.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: require.resolve('./src/globals.js'),
use: 'exports-loader?file,parse=helpers.parse'
}
]
}
};
./src/globals.js
var file = 'blah.txt'
var helpers = {
test: function() { console.log('test something'); },
parse: function() { console.log('parse something'); }
}
./src/index.js
import { file } from './globals.js'
console.log('the file', file);
My application builds fine, but when I attempt to run it I get:
WebpackOptionsValidationError: Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.module.rules[0].test should be one of these:
- configuration.module.rules[0].test: The provided value "./src/globals.js" is not an absolute path!
To be completely clear, I understand the difference between an absolute and a relative path, and I know that the value I'm using is a relative path. My confusion is two-fold:
require.resolveallows relative paths, so why can I not use it here?- If I cannot use a relative path, how can I refer to that file otherwise?
I tried using an absolute path for the test property like so:
test: require.resolve(path.join(__dirname, 'src/globals.js'))
But I get this error when I attempt to run:
Error: Cannot find module '/workspace/my-app/dist/src/globals.js
So I'm stuck. How can I properly configure this loader to reference that file appropriately?
Getting
exports-loaderto workExports loader is a webpack loader that allows to dynamically add
exportssentences to javascript files loaded with it. For instance, yourglobals.jsfile does not have anyexportin it, only thefileandhelpersvariables, yet withexports-loaderit can work as if it hadexportclauses.Loading webpack loaders
Basically, to use a loader we must to provide a
testand anuseclauses. Thetestcan be a regex, an array or an object, and basically it decides which files will use certain loaders.The
useclause decides which loaders will be applied to the files that match thetestregex.In this case, we should -for instance- instruct webpack to load
globals.jswithexports-loader:This is -afaik- the most common way to use loaders. Webpack, however, has a lot of configuration options and different valid syntaxes.
Once we do this, when webpack finds a
requireor animportagains aglobals.jsfile, it will use theexports-loader.On other hand,
exports-loaderworks by modifying therequirecalls to instruct it how to extract variables in the required file. As in their docs:file.js
app.js
So, basically you need two things to get
exports-loaderto work:Use
requireorimportwith their special syntax.Load the loader in the
webpack.config.jsas usual (they skip this in their documentation).Instead, you're trying to use this specific
exports-loadersyntax in yourwebpack.config.jsfile, and then using it withimport.So, bad news are that
exports-loaderneed some special formatting in everyrequireorimportstatement to do its magic. You just cannot specify this in your config file as you are trying (or, at least, I don't know how to).So, to get it to work, you need to:
webpack.config.jsas stated above.index.jsfile so it uses theexports-loadermagic: