12

I'm building an isomorphic React/React-Router/Redux/Webpack application and I'm attempting to implement server side rendering.

My directory looks like:

/client
    /actions
    /components
    /containers
/server
    /server.js

In my webpack config, I have aliases set up for all the folders inside client:

var path_base = path.resolve(__dirname, '..');
const resolve = path.resolve;
const base = function() {
  var args = [path_base];
  args.push.apply(args, arguments);
  return resolve.apply(resolve,args);
};
const resolve_alias = base.bind(null, 'src/client');
const aliases = [
  'actions',
  'components',
  'constants',
  'containers',
  'middleware',
  'reducers',
  'routes',
  'store',
  'styles',
  'utils',
  'validation'
];

so that inside the code that gets bundled by webpack, I can do:

import { Widget } from 'components'; 

and that import gets resolved by webpack.

Now in my server code, in order to do the rendering, I have to import some of my client files, like routes/index.js. The problem I'm running into when I import my routes file, it's using a webpack alias to another file, say components or containers so naturally, the node js require system can't resolve it.

How do I fix something like that? I looked at this question and it talks about essentially setting up the same aliases that exist in webpack with mock-require. But then the issue becomes that my routes file imports all my components which then all import things like stylesheets, images, etc. Should I then be using something like webpack-isomorphic-tools?

The guides I've been looking at (this for example) are all great at showing how server side rendering is accomplished but none of them really talk about how to resolve all the requires and whatnot.

15
  • It sounds like there are several questions here: (a) how do I use the aliases when running server-side, and (b) how do I handle included resources like stylesheets on the server. One solution is to run your server code through webpack too. You can use target: node in your config and it will optimize it for node during the build (i.e. it won't bundle node includes). I do this sometimes for code that uses Babel. Short of doing a build, definitely don't use aliases. Any solution will be hacky at best. Commented Jan 8, 2016 at 23:22
  • Why shouldn't I use aliases? Commented Jan 9, 2016 at 1:05
  • Aliases are fine when you're doing a build with webpack. Your problem is because you are using aliases in a webpack build and trying to get the same code to work outside a webpack build. My point was that to use the aliases, you need to build your server code too (which will make the aliases work just fine). Without the build, the only way to get aliases to work is to hack it together, which is where your problem is. Hacks are bad, so use the aliases and build your server code too, or just abandon the aliases. Commented Jan 9, 2016 at 1:20
  • Then using something like webpack-isomorphic-tools shouldn't be a problem then because that supports aliases, for both server and client code. Commented Jan 9, 2016 at 1:46
  • 1
    gist.github.com/startupthekid/3223a866616b6dc59e4d5d4fc03275a7. I included my aliases file, all the configs, and then my scripts from my package.json. There's a ton of files, four for the server and client each (base config, dev config, production config, production entry file, and development entry file) and then a base configuration file as well as the universal webpack config file. I don't have all of them in the gist (I haven't set up production configs yet) but that should be a good start for you Commented Oct 6, 2016 at 3:51

4 Answers 4

6

After battling with this issue for 2 days I settled on babel-plugin-webpack-alias. What you need to do to resolve paths with that is:

  1. $ npm install --save-dev babel-plugin-webpack-alias
  2. Add the plugin to your .babelrc
  3. Add the aliases to your webpack.config (make sure you use path.join())
  4. Refer to this post if you have problems loading styles

The other option I tried was universal-webpack but I found it to be a bit verbose. If you want to see roughly how the whole server-side loading works, you can check out this video.

Sign up to request clarification or add additional context in comments.

1 Comment

babel-plugin-webpack-alias works, but seems like it breaks Jest. Isolating this plugin to Babel's development environment (via the env config key) fixed that for me
1

If you really want them, run your server side code through babel and use this plugin: https://www.npmjs.com/package/babel-plugin-module-alias which will let you do the same thing as webpack.

Edit: This one works a lot better: https://github.com/jagrem/babel-resolve-relative-module it allows multiple paths

3 Comments

What's the reasoning behind not using them?
It just seems to cause problems plus you have to rely on using at the very least a plugin on the server, and probably running your whole code base through Babel. Which I guess is fine but if the only reason you pull in Babel is for aliases, seems like a lot of work
THANK YOU for linking to that Babel plugin! I hadn't thought to look on the Babel side of things for aliasing. This helped me a lot!
0

Try to use NODE_PATH. Node will always look for a module in this path during require calls. It allows to short cut your relative paths as you want.

// turn this
import {Widget} from '../../components';

// into this
import {Widget} from 'components';

See Node.js docs for more information.

P.S. this thing is very sensitive, so use it carefully. Now your code tightly depends from the environment and may break somewhere.

Comments

0

If you use webpack-isomorphic-tools then it'll take your webpack config into account for your server side which will make all your aliases work.

https://www.npmjs.com/package/webpack-isomorphic-tools

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.