Issue 1:
To reproduce, just clone https://g.trusktr.io/trusktr/webpack-test.git, then run

npm install
webpack

then look at ./built/shared-modules.js to notice that it doesn't contain any shared modules.

Problem:

Seems like the problem is that npm installs local packages, those listed with file:path format, in such a way that Webpack doesn't detect shared/common modules?

Details:

I have a tree that looks like this after running Webpack. The built folder is the output folder:

.
├── built
│ ├── __app__
│ │ └── client
│ │ └── app.module.js
│ ├── shared-modules.js
│ ├── trusktr_lib2
│ │ └── module.js
│ └── trusktr_scratchpaper
│ ├── client.module.js
│ └── foo
│ └── bar.module.js
├── node_modules
│ ├── rocket_module
│ │ └── package.json
│ ├── trusktr_lib2
│ │ ├── module.js
│ │ ├── node_modules
│ │ │ ├── lower-case
│ │ │ │ ├── LICENSE
│ │ │ │ ├── README.md
│ │ │ │ ├── lower-case.js
│ │ │ │ └── package.json
│ │ │ └── upper-case
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── package.json
│ │ │ └── upper-case.js
│ │ └── package.json
│ └── trusktr_scratchpaper
│ ├── client.module.js
│ ├── foo
│ │ └── bar.module.js
│ ├── node_modules
│ │ └── upper-case
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── package.json
│ │ └── upper-case.js
│ └── package.json
├── package.json
└── packages
├── __app__
│ └── client
│ └── app.module.js
├── rocket_module
│ └── package.json
├── trusktr_lib2
│ ├── module.js
│ └── package.json
└── trusktr_scratchpaper
├── client.module.js
├── foo
│ └── bar.module.js
└── package.json

Everything in the packages folder is treated as a local node_module and listed in the root package.json using file:path notation:

{
"dependencies": {
"rocket_module": "file:./packages/rocket_module",
"trusktr_lib2": "file:./packages/trusktr_lib2",
"trusktr_scratchpaper": "file:./packages/trusktr_scratchpaper"
}
}

I then run npm install in the root folder, which places the local packages into the top-level node_modules folder:

├── node_modules
│ ├── rocket_module
│ │ └── package.json
│ ├── trusktr_lib2
│ │ ├── module.js
│ │ ├── node_modules
│ │ │ ├── lower-case
│ │ │ │ ├── LICENSE
│ │ │ │ ├── README.md
│ │ │ │ ├── lower-case.js
│ │ │ │ └── package.json
│ │ │ └── upper-case
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── package.json
│ │ │ └── upper-case.js
│ │ └── package.json
│ └── trusktr_scratchpaper
│ ├── client.module.js
│ ├── foo
│ │ └── bar.module.js
│ ├── node_modules
│ │ └── upper-case
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── package.json
│ │ └── upper-case.js
│ └── package.json

We can see that each package contains it's own node_modules folder, and there are duplicate dependencies, like upper-case, but the duplicates are of the same version.

Now, I'm adding each of those node_modules folders to webpack.config.js, so it looks like this:

module.exports = {
entry: {
"__app__/client/app.module.js": "./packages/__app__/client/app.module.js",
"trusktr_lib2/module.js": "./packages/trusktr_lib2/module.js",
"trusktr_scratchpaper/client.module.js": "./packages/trusktr_scratchpaper/client.module.js",
"trusktr_scratchpaper/foo/bar.module.js": "./packages/trusktr_scratchpaper/foo/bar.module.js"
},
output: {
path: "/root/built"
filename: "[name]",
},
plugins: [ new webpack.optimize.CommonsChunkPlugin("shared-modules.js") ],
resolve: {
fallback: [
"/root/node_modules/trusktr_lib2/node_modules",
"/root/node_modules/trusktr_scratchpaper/node_modules"
]
}
module: {
loaders: [
{ test: /\.css$/, loader: "style!css" }
]
},
}

Now when I run webpack it compiles the the files into the built folder. The output shared-modules.js file looks like this:

/******/ (function(modules) { // webpackBootstrap
/******/ // install a JSONP callback for chunk loading
/******/ var parentJsonpFunction = window["webpackJsonp"];
/******/ window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules) {
/******/ // add "moreModules" to the modules object,
/******/ // then flag all "chunkIds" as loaded and fire callback
/******/ var moduleId, chunkId, i = 0, callbacks = [];
/******/ for(;i < chunkIds.length; i++) {
/******/ chunkId = chunkIds[i];
/******/ if(installedChunks[chunkId])
/******/ callbacks.push.apply(callbacks, installedChunks[chunkId]);
/******/ installedChunks[chunkId] = 0;
/******/ }
/******/ for(moduleId in moreModules) {
/******/ modules[moduleId] = moreModules[moduleId];
/******/ }
/******/ if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules);
/******/ while(callbacks.length)
/******/ callbacks.shift().call(null, __webpack_require__);
/******/ if(moreModules[0]) {
/******/ installedModules[0] = 0;
/******/ return __webpack_require__(0);
/******/ }
/******/ };

/******/ // The module cache
/******/ var installedModules = {};

/******/ // object to store loaded and loading chunks
/******/ // "0" means "already loaded"
/******/ // Array means "loading", array contains callbacks
/******/ var installedChunks = {
/******/ 4:0
/******/ };

/******/ // The require function
/******/ function __webpack_require__(moduleId) {

/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;

/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };

/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

/******/ // Flag the module as loaded
/******/ module.loaded = true;

/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }

/******/ // This file contains only the entry chunk.
/******/ // The chunk loading function for additional chunks
/******/ __webpack_require__.e = function requireEnsure(chunkId, callback) {
/******/ // "0" is the signal for "already loaded"
/******/ if(installedChunks[chunkId] === 0)
/******/ return callback.call(null, __webpack_require__);

/******/ // an array means "currently loading".
/******/ if(installedChunks[chunkId] !== undefined) {
/******/ installedChunks[chunkId].push(callback);
/******/ } else {
/******/ // start chunk loading
/******/ installedChunks[chunkId] = [callback];
/******/ var head = document.getElementsByTagName('head')[0];
/******/ var script = document.createElement('script');
/******/ script.type = 'text/javascript';
/******/ script.charset = 'utf-8';
/******/ script.async = true;

/******/ script.src = __webpack_require__.p + "" + chunkId + "." + ({"0":"__app__/client/app.module.js","1":"trusktr_scratchpaper/client.module.js","2":"trusktr_scratchpaper/foo/bar.module.js","3":"trusktr_lib2/module.js"}[chunkId]||chunkId) + "";
/******/ head.appendChild(script);
/******/ }
/******/ };

/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;

/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;

/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ })
/************************************************************************/
/******/ ([]);

We can see that there's no common modules in this entry chunk made by the CommonsChunkPlugin. Instead, the modules are duplicated in the initial chunk files.

Here's the built/trusktr_lib2/module.js file:

webpackJsonp([3,4],[
/* 0 */
/***/ function(module, exports, __webpack_require__) {

// Write your package code here!
var lowercase = __webpack_require__(2)
var uppercase = __webpack_require__(1)

console.log(' --- ', lowercase('SHOULD BE LOWERCASE!'))
console.log(' --- ', uppercase('Should be uppercase!'))

Lib = {
hello: function() {
return 'Goodbye.'
}
} // ----------------------------------------------------------------------------------------------------------------------------------------------------

/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {

/**
* Special language-specific overrides.
*
* Source: ftp://ftp.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt
*
* @type {Object}
*/
var LANGUAGES = {
tr: {
regexp: /[\u0069]/g,
map: {
'\u0069': '\u0130'
}
},
az: {
regexp: /[\u0069]/g,
map: {
'\u0069': '\u0130'
}
},
lt: {
regexp: /[\u0069\u006A\u012F]\u0307|\u0069\u0307[\u0300\u0301\u0303]/g,
map: {
'\u0069\u0307': '\u0049',
'\u006A\u0307': '\u004A',
'\u012F\u0307': '\u012E',
'\u0069\u0307\u0300': '\u00CC',
'\u0069\u0307\u0301': '\u00CD',
'\u0069\u0307\u0303': '\u0128'
}
}
}

/**
* Upper case a string.
*
* @param {String} str
* @return {String}
*/
module.exports = function (str, locale) {
var lang = LANGUAGES[locale]

str = str == null ? '' : String(str)

if (lang) {
str = str.replace(lang.regexp, function (m) { return lang.map[m] })
}

return str.toUpperCase()
}

/***/ },
/* 2 */
/***/ function(module, exports, __webpack_require__) {

/**
* Special language-specific overrides.
*
* Source: ftp://ftp.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt
*
* @type {Object}
*/
var LANGUAGES = {
tr: {
regexp: /\u0130|\u0049|\u0049\u0307/g,
map: {
'\u0130': '\u0069',
'\u0049': '\u0131',
'\u0049\u0307': '\u0069'
}
},
az: {
regexp: /[\u0130]/g,
map: {
'\u0130': '\u0069',
'\u0049': '\u0131',
'\u0049\u0307': '\u0069'
}
},
lt: {
regexp: /[\u0049\u004A\u012E\u00CC\u00CD\u0128]/g,
map: {
'\u0049': '\u0069\u0307',
'\u004A': '\u006A\u0307',
'\u012E': '\u012F\u0307',
'\u00CC': '\u0069\u0307\u0300',
'\u00CD': '\u0069\u0307\u0301',
'\u0128': '\u0069\u0307\u0303'
}
}
}

/**
* Lowercase a string.
*
* @param {String} str
* @return {String}
*/
module.exports = function (str, locale) {
var lang = LANGUAGES[locale]

str = str == null ? '' : String(str)

if (lang) {
str = str.replace(lang.regexp, function (m) { return lang.map[m] })
}

return str.toLowerCase()
}

/***/ }
]);

and here's the built/trusktr_scratchpaper/client.module.js file:

webpackJsonp([1,4],[
/* 0 */
/***/ function(module, exports, __webpack_require__) {

// Write your package code here!
var uppercase = __webpack_require__(1)
var local = __webpack_require__(!(function webpackMissingModule() { var e = new Error("Cannot find module \"./local\""); e.code = 'MODULE_NOT_FOUND'; throw e; }()))

console.log(' --- ', uppercase('Should be uppercase! (scratchpaper)'))
console.log(' --- local import: ', local)

// a Meteor export that other packages can use if they depend on this package.
Lib = {
hello: function() {
return 'Hello.'
}
}

/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {

/**
* Special language-specific overrides.
*
* Source: ftp://ftp.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt
*
* @type {Object}
*/
var LANGUAGES = {
tr: {
regexp: /[\u0069]/g,
map: {
'\u0069': '\u0130'
}
},
az: {
regexp: /[\u0069]/g,
map: {
'\u0069': '\u0130'
}
},
lt: {
regexp: /[\u0069\u006A\u012F]\u0307|\u0069\u0307[\u0300\u0301\u0303]/g,
map: {
'\u0069\u0307': '\u0049',
'\u006A\u0307': '\u004A',
'\u012F\u0307': '\u012E',
'\u0069\u0307\u0300': '\u00CC',
'\u0069\u0307\u0301': '\u00CD',
'\u0069\u0307\u0303': '\u0128'
}
}
}

/**
* Upper case a string.
*
* @param {String} str
* @return {String}
*/
module.exports = function (str, locale) {
var lang = LANGUAGES[locale]

str = str == null ? '' : String(str)

if (lang) {
str = str.replace(lang.regexp, function (m) { return lang.map[m] })
}

return str.toUpperCase()
}

/***/ }
]);

We see here that the upper-case module has been duplicated in both of these initial chunk files.

Issue 2:
Feature request

What is the expected behavior?

resolve.mainFields should support Conditional Exports in nodejs

"exports": {
".": {
"require": "./dist/my-lib.cjs",
"import": "./dist/my-lib.mjs"
}
}