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

thank

+3


source to share


2 answers


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!

+3


source


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'
}

      

0


source







All Articles