How can I not bind node_modules but use them normally in node.js?
Architecture
I would like to share the code between client and server side. I have defined aliases in 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/'),
}
},
Problem
Now, on the server side, I need to enable webpack to recognize the correct paths when I need a file. for example
require('app/somefile.js')
will fail in pure node.js because it can't find the app folder.
What I need (read the section "What I need to update")
I need to be able to use webpack aliases. I was thinking about package the whole backend without a file from node_modules. So when starting the server it will use node_modules from the node_modules folder instead of the minijs file (why? 1st: this doesn't work.2nd: bad because node_modules are compiled on the platform, so I don't want my win files on unix server).
Output:
- Compiled
server.js
file without node_modules included. - Let's
server.js
use node_modules;
What do I need to update
As I noticed at https://github.com/webpack/webpack/issues/135 , creating a bundled server.js will mess up all the io activity file paths.
A better idea would be to leave the node.js server files as they are, but replace the method require
provided with a custom webpack require
that takes account of account configurations like aliases (others?) .. Can be done like require .js made to run on node.js server.
What i tried
By adding this plugin to 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 server.js file that only contains my server code. Then server.bundle.js is created which is not used. But the problem is that webpack includes the function webpackJsonp
in the file server.bundle.js
. Therefore, both the client and the server will not work.
This should be a way to just disable node_modules for one entry.
What I tried # 2
I managed to exclude the path, but it doesn't work because it's already changed. So the source looks like require(3)
instead of require('my-module')
. Each line requires conversion to integer, so it doesn't work.
For this to work, I also need to fix the required function that webpack exports to add the required node.js function (this is easy to do manually, but should be done automatically).
What I tried # 3
In webpack config:
{target: "node"}
This only adds the variable exports
(not sure what else it does, because I was differentiating the output).
What I tried # 4 (almost there)
Using
require.ensure('my_module')
and then replacing all occurrences r(2).ensure
with the query. I don't know if the part is r(2)
always the same and because of this it cannot be automated.
solved
Thanks to ColCh for enlightening me on how to do it.
require = require('enhanced-require')(module, require('../../webpack.config'));
By changing the method require
in node.js, it will make node.js pass everything, requiring through the webpack function require
that allows us to use aliases and other gifts! Thanks ColCh!
Related
- https://www.bountysource.com/issues/1660629-what-s-the-right-way-to-use-webpack-specific-functionality-in-node-js
- https://github.com/webpack/webpack/issues/135
- http://webpack.github.io/docs/configuration.html#target
- https://github.com/webpack/webpack/issues/458
- How can I create "web" and "node" versions of a package at the same time using Webpack?
- http://nerds.airbnb.com/isomorphic-javascript-future-web-apps/
thank
source to share
Thanks to ColCh for telling me how to do it here .
require = require('enhanced-require')(module, require('../../webpack.config'));
By changing the method require
in node.js, it will make node.js pass everything required through the webpack function require
, which allows us to use aliases and other gifts! Thanks ColCh!
source to share
My solution was:
{
// make sure that webpack will externalize
// modules using Node 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'
}
source to share