Reputation: 121
I would like to share code between client and server side. I have defined aliases in the webpack config:
resolve: {
// Absolute paths: https://github.com/webpack/webpack/issues/109
alias: {
server : absPath('/src/server/'),
app : absPath('/src/app/'),
client : absPath('/src/client/'),
}
},
Now on the server side I need to include webpack in order to recognize the correct paths when I require a file. For example
require('app/somefile.js')
will fail in pure node.js because can't find the app folder.
I need to be able to use the webpack aliases. I was thinking about making a bundle of all the server part without any file from node_modules. In this way when the server starts it will use node_modules from the node_modules folder instead of a minified js file (Why? 1st: it doesn't work. 2nd: is bad, because node_modules are compiled based on platform. So I don't want my win files to go on a unix server).
Output:
server.js
file without any node_modules included.server.js
to use node_modules;As I've noticed in https://github.com/webpack/webpack/issues/135 making a bundled server.js will mess up with all the io operation file paths.
A better idea would be to leave node.js server files as they are, but replace the require
method provided with a custom webpack require
which takes in account configurations such as aliases (others?)... Can be done how require.js has done to run on node.js server.
By adding this plugin in webpack
new webpack.optimize.CommonsChunkPlugin(/* chunkName= */"ignore", /* filename= */"server.bundle.js")
Entries:
entry: {
client: "./src/client/index.js",
server: "./src/server/index.js",
ignore: ['the_only_node_module'] // But I need to do that for every node_module
},
It will create a file server.js which only contains my server code. Then creates a server.bundle.js which is not used. But the problem is that webpack includes the webpackJsonp
function in the server.bundle.js
file. Therefore both the client and server will not work.
It should be a way to just disable node_modules on one entry.
I've managed to exclude the path, but requires doesn't work because are already minified. So the source looks like require(3)
instead of require('my-module')
. Each require string has been converted to an integer so it doesn't work.
In order to work I also need to patch the require function that webpack exports to add the node.js native require function (this is easy manually, but should be done automatically).
In the webpack configuration:
{target: "node"}
This only adds an exports
variable (not sure about what else it does because I've diffed the output).
Using
require.ensure('my_module')
and then replacing all occurrences of r(2).ensure
with require. I don't know if the r(2)
part is always the same and because of this might not be automated.
Thanks to ColCh for enlighten me on how to do here.
require = require('enhanced-require')(module, require('../../webpack.config'));
By changing the require
method in node.js it will make node.js to pass all requires trough the webpack require
function which allow us to use aliases and other gifts! Thanks ColCh!
Thanks
Upvotes: 3
Views: 4417
Reputation: 29
My solution was:
{
// make sure that webpack will externalize
// modules using Node's module API (CommonJS 2)
output: { ...output, libraryTarget: 'commonjs2' },
// externalize all require() calls to non-relative modules.
// Unless you do something funky, every time you import a module
// from node_modules, it should match the regex below
externals: /^[a-z0-9-]/,
// Optional: use this if you want to be able to require() the
// server bundles from Node.js later
target: 'node'
}
Upvotes: 0
Reputation: 121
Thanks to ColCh for enlighten me on how to do here.
require = require('enhanced-require')(module, require('../../webpack.config'));
By changing the require
method in node.js it will make node.js to pass all requires trough the webpack require
function which allow us to use aliases and other gifts! Thanks ColCh!
Upvotes: 3