Open OlliV opened 5 years ago
Can you elaborate on what you mean? All of our main builders are indeed compiled via ncc, and the exports remain intact.
Also, this simple example preserves the exports:
// t.js
exports.foo = 'bar';
$ ncc build t.js
1kB dist/index.js
1kB [285ms] - ncc 0.16.0
> require('./dist')
{ foo: 'bar' }
Interesting. I was using TS and all I got was this:
console.log(require('...'));
{ }
I need to try to find the min reproduction of the issue. I was using several exports and a default export. Once that didn't work I also tried to reproduce TS-like exports in the node.js way but I was still getting an empty object.
Ok the issue seems to be related to npm link
and dynamic requires.
Let's say you have project-1 that is built with ncc
and there is a function in project-1 that can dynamically require and execute code from any path given as an arg.
Then project-2 uses npm link project-1
and calls that function passing a path of file in its own source tree. So far everything works and the code is loaded and can be executed by project-1. However, if the file from project-2 that is being executed by project-1 now also tries to require something from project-1 only in this case will require('project-1')
return an empty object.
I have a very interesting repro without npm link
. It seems like dynamic require works fine if the code build with ncc
is not in the node_modules
directory.
https://files-8mwa86l42.now.sh
ncc-issue-repro/
ncc-issue-repro/package.json
ncc-issue-repro/yarn.lock
ncc-issue-repro/index.js
ncc-issue-repro/node_modules/
ncc-issue-repro/node_modules/.bin/
ncc-issue-repro/node_modules/.bin/micri
ncc-issue-repro/node_modules/.yarn-integrity
ncc-issue-repro/node_modules/test/
ncc-issue-repro/node_modules/test/package.json
ncc-issue-repro/node_modules/test/yarn.lock
ncc-issue-repro/node_modules/test/tsconfig.json
ncc-issue-repro/node_modules/test/src/
ncc-issue-repro/node_modules/test/src/index.ts
ncc-issue-repro/node_modules/test/dist/
ncc-issue-repro/node_modules/test/dist/index.d.ts
ncc-issue-repro/node_modules/test/dist/index.js
ncc-issue-repro/test/
ncc-issue-repro/test/package.json
ncc-issue-repro/test/yarn.lock
ncc-issue-repro/test/tsconfig.json
ncc-issue-repro/test/src/
ncc-issue-repro/test/src/index.ts
ncc-issue-repro/test/dist/
ncc-issue-repro/test/dist/index.js
ncc-issue-repro/test/dist/index.d.ts
ncc-issue-repro/run.sh
I'm running here first the index.js
file that just requires test
from both the direct subdir as well as using the standard module require string format, and that works fine. 'here'
is a string exported by the module compiled with ncc
.
Now things get really interesting if I execute the module compiled with ncc
and require index.js
dynamically from there. As you can see from the logs the second case, which should be the normal use case, now sees undefined
.
./run.sh
+ node index.js
Path: /home/hbp/tmp/ncc-issue-repro/index.js
node_modules: here
Path: /home/hbp/tmp/ncc-issue-repro/index.js
local here
+ node ./node_modules/test/dist/index.js
Path: /home/hbp/tmp/ncc-issue-repro/index.js
node_modules: undefined
Path: /home/hbp/tmp/ncc-issue-repro/index.js
local here
Here is the code so you don't necessarily need to open the tar file:
index.js
const {findMe: a} = require('test');
console.log('node_modules:', a);
const {findMe: b} = require('./test');
console.log('local', b);
test/index.js
const {findMe: a} = require('test');
console.log('node_modules:', a);
const {findMe: b} = require('./test');
console.log('local', b);
[hbp@hbp-mac-fedora]~/tmp/ncc-issue-repro% cat test/dist/index.js
module.exports=function(e,r){"use strict";var t={};function __webpack_require__(r){if(t[r]){return t[r].exports}var u=t[r]={i:r,l:false,exports:{}};e[r].call(u.exports,u,u.exports,__webpack_require__);u.l=true;return u.exports}__webpack_require__.ab=__dirname+"/";function startup(){return __webpack_require__(325)}return startup()}({325:function(e,r,t){"use strict";var u=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(r,"__esModule",{value:true});const n=u(t(622));r.findMe="here";function fn(){const e=n.default.resolve(process.cwd(),"index.js");console.log(`Path: ${e}`);require(e)}fn()},622:function(e){e.exports=require("path")}});
test/index.ts
import path from 'path';
export const findMe = 'here';
function fn() {
const filePath = path.resolve(process.cwd(), 'index.js');
console.log(`Path: ${filePath}`);
require(filePath);
}
fn();
Further on it seems this occurs if I require
the same file that executed my code. If I use a physically copy of index.js
that contains findMe
then it's fine. Symlink doesn't work. The copy of the file can be exact copy but it must be located in a different path and can't be linked.
Yeah I think I may be running into this when trying to use the eslint cli packaged in for a github action?
It seems that by default
ncc
(or webpack) isn't configured to preserve exports. Is it possible to do that?