One project with multiple package.json files
OK, so after some more research I stumbled upon Lerna which mostly allows me to do what I wanted (from what I've seen so far). It requires specific project tree setup, like this:
project_root/ node_modules/ packages/ components/ // Components shared between projects components/ MyComponent.jsx index.jsx legacy/ output/ build.js // React 0.14 build node_modules/ package.json // project specific dependencies index.jsx // project specific entry .babelrc modern/ output/ build.js // React 16 build node_modules/ package.json // project specific dependencies index.jsx // project specific entry .babelrc package.json // contains devDependencies shared between projects lerna.json webpack.config.js index.html
Then, in components/index.jsx I specified require commands for different versions based on global variable:
if(PROJECT_SRC == "legacy"){ React = require('../legacy/node_modules/react'); ReactDOM = require('../legacy/node_modules/react-dom');} else { React = require('../modern/node_modules/react'); ReactDOM = require('../modern/node_modules/react-dom');}
Note: This is probably bad practice but the only way at the moment I could include different React versions in the build. I'll have to see what problems arise with this approach after the whole project changes to this model.
In webpack.config.js I configured two exports - one for modern and one for legacy. Each points to a different entry index.jsx file, uses webpack.DefinePlugin to set global variable to "legacy" or "modern", and specifies path to common components module to resolve: ['node_modules', path.resolve(__dirname, 'components')]
webpack.config for a single project output looks something like this:
{ entry: "./packages/legacy/index.jsx", target: "web", output: { filename: "build.js", path: __dirname + "/packages/legacy/dist/", libraryTarget: "var", library: "lib_name" }, devtool: "source-map", resolve: { extensions: [".js", ".jsx", ".json"], modules: ['node_modules', path.resolve(__dirname, 'components')] }, plugins: plugins_legacy, module: { loaders: [ { test: /\.jsx?$/, loader: "babel-loader", exclude: /node_modules/ } ] } }
Feel free to comment or point to problems but I hope this will help somebody in the future! :)