添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Im very new to Node and is possible its just my lack of knowledge, in that case Im sorry, I opened the issue nodejs/node#18267 thinking it was a node bug but the issue grpc/grpc#13049 is telling: "The __dirname variable is explicitly documented as referring to the full path of the directory containing the current module file."

There is a comment of me after this block with a script to reproduce the project.
Below the detail steps to reproduce the problem:

__dirname => "/"
var binding_path = binary.find(path.resolve(path.join(__dirname, './package.json'))); /* node_modules/bcrypt/bcrypt.js [line:0005] */

/* INNER path.join(__dirname, './package.json') RETURNS '/package.json' */

/* <node_internals>/path.js [ {function=path.resolve} line:1174] */
resolvedPath => ""
path => "/package.json"
resolvedPath => ""
resolvedAbsolute => false

resolvedPath = path + '/' + resolvedPath; /* <node_internals>/path.js [line:1174] */

resolvedPath => "/package.json/"
path => "/package.json"
resolvedPath => "/package.json/"

resolvedAbsolute = path.charCodeAt(0) === 47/*/*/; /* <node_internals>/path.js [line:1175] */

resolvedAbsolute => true

resolvedPath = normalizeStringPosix(resolvedPath, !resolvedAbsolute); /* <node_internals>/path.js [line:1182] */

resolvedPath => "package.json"

"/package.json" <= return '/' + resolvedPath; /* <node_internals>/path.js [line:1186] */

/* node_modules/bcrypt/node_modules/node-pre-gyp/lib/pre-binding.js [ {function=binary.find} line:0015] /
/
binary.find execute against "/package.json" and throw error: "package.json does not exist at /package.json"
/* the problem looks happens because of lack of calling "process.cwd()" inside [ {function=path.resolve} line:1174] on the flow */

npm install webpack npm install webpack-node-externals npm install awesome-typescript-loader --save-dev npm install file-loader npm install ignore-loader npm install ts-loader npm install bcrypt @types/bcrypt npm install jshint npm install aws-sdk /* aws-sdk above to stop compiler error */ tsc --init echo '' > ./package.json cat <<EOT>> ./package.json "name": "stp003-Node", "version": "1.0.0", "description": "learn", "private": "true", "main": "index.js", "scripts": { "build": "webpack" "keywords": [], "author": "", "license": "ISC", "devDependencies": { "awesome-typescript-loader": "^3.4.1", "typescript": "^2.6.2", "webpack": "^3.10.0" "dependencies": { "@types/bcrypt": "^1.0.0", "aws-sdk": "^2.185.0", "bcrypt": "^1.0.3", "file-loader": "^1.1.6", "ignore-loader": "^0.1.2", "jshint": "^2.9.5", "ts-loader": "^3.3.0", "webpack-node-externals": "^1.6.0" echo '' > ./tsconfig.json cat <<EOT>> ./tsconfig.json "compilerOptions": { /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ "target": "ESNEXT", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ "module": "ESNext", /* Enable all strict type-checking options. */ "strict": true, /* Generates corresponding '.map' file. */ "sourceMap": true echo '' > webpack.config.js cat <<EOT>> webpack.config.js module.exports = { devtool: "inline-source-map", entry: "./ts/index.ts", target: "node", output: { filename: "./index.js" resolve: { extensions: ["*", ".js", ".ts", ".tsx", ".json"] module: { loaders: [ test: /\.tsx?$/, loader: "awesome-typescript-loader", /* alternative ts-loader */ test: /\.(css|cs|htm|html)?$/, loader: "ignore-loader" test: /npm-cli\.js?$/, loader: "ignore-loader" node: { ajv: "empty", bcrypt: "empty", child_process: "empty", fs: "empty", fsevents: "empty", net: "empty", npm: "empty" mkdir -p ./ts/{M,V,C,T} echo '' > ./index.js echo '' > ./ts/T/dataUtil.ts cat <<EOT>> ./ts/T/dataUtil.ts export class DataUtil { printIt(toPrint: string): void { console.log(toPrint); echo '' > ./ts/T/cryptUtil.ts cat <<EOT>> ./ts/T/cryptUtil.ts import * as bcrypt from 'bcrypt'; export class cryptUtil { private _rounds: number = 10; //0xf49f6cd693d04c7ebe6928429a24f2ce; public get rounds(): number { return this._rounds; public set rounds(rounds: number) { this._rounds = rounds; public getSalt(): string { return bcrypt.genSaltSync(this.rounds); public getSaltAsynchronous( callback: ((err: Error, salt: string) => void) ): void { bcrypt.genSalt(this.rounds, callback); public BCryptHashGet(passw: string): string { return this.BCryptHashGet(passw); public BCryptHashGetAsynchronous( passw: string, callback: ((err: Error, hash: string) => void) ): void { this.getSaltAsynchronous((err: Error, salt: string) => { bcrypt.hash(this.rounds,passw,callback); public BCryptHashCompare(passw: string, hash: string): boolean { return bcrypt.compareSync(passw, hash); public BCryptHashCompareAsynchronous( passw: string, hash: string, callback: ((err: Error, isMatch: boolean) => void) ): void { bcrypt.compare(passw, hash, callback); echo '' > ./ts/M/animal.ts cat <<EOT>> ./ts/M/animal.ts export class Animal { _name: string; set name(parmName: string) { this._name = parmName; get name(){ return this._name; echo '' > ./ts/M/person.ts cat <<EOT>> ./ts/M/person.ts import { Animal } from "./animal"; import { DataUtil } from "./../T/dataUtil"; import { cryptUtil } from "./../T/cryptUtil"; export class Person { _crypt: cryptUtil; _animal: Animal; _datautil: DataUtil; constructor() { this._animal = new Animal(); this._datautil = new DataUtil(); this._crypt = new cryptUtil(); _name: string = ""; set name(parmName: string) { this._name = parmName; get name() { return this._name; echoname() { console.log("Plaintext:" + this.name); echonamecrypt() { console.log("Crypto:" + this._crypt.BCryptHashGet(name)); echo '' > ./ts/index.ts cat <<EOT>> ./ts/index.ts import { Person } from "./M/person"; class index { main() { let p = new Person(); p.name = "nameperson"; p.echoname(); //p.echonamecrypt(); let idx = new index(); idx.main(); npm run build node ./index.js /home/myuser/myprojects/base/index.js:32779 throw new Error("package.json does not exist at " + package_json_path); Error: package.json does not exist at /package.json at Object.exports.find (/home/myuser/myprojects/base/index.js:32779:15) at Object.<anonymous> (/home/myuser/myprojects/base/index.js:66705:27) at Object.<anonymous> (/home/myuser/myprojects/base/index.js:66906:30) at __webpack_require__ (/home/myuser/myprojects/base/index.js:20:30) at Object.<anonymous> (/home/myuser/myprojects/base/index.js:66658:65) at __webpack_require__ (/home/myuser/myprojects/base/index.js:20:30) at Object.__webpack_require__.name.parmName._name (/home/myuser/myprojects/base/index.js:66594:71) at __webpack_require__ (/home/myuser/myprojects/base/index.js:20:30) at Object.<anonymous> (/home/myuser/myprojects/base/index.js:66573:68) at __webpack_require__ (/home/myuser/myprojects/base/index.js:20:30)

Im not using it in frontend, i havent frontend its a code to learn, im learning typescript/nodejs and my webpack.config.js has target: "node".
Updated node and npm.
node --version => v8.9.4
npm --version => 5.6.0
I just want build a serverside bundle like it :

https://hashnode.com/post/is-there-any-reason-to-bundle-server-side-code-with-webpack-cja6i7ygs05a5xpwuitg0fu7r

There is a bundler comparison here:
https://stackshare.io/stackups/webpack-vs-grunt-vs-backpack-vs-gulp

@Mark086 I understand your use-case. However, bundling your code will break native modules like this one.

As a workaround, you can exclude some dependencies using the IgnorePlugin

NodeJS native modules contains DLLs and glue code and the module initialization code loads them into the NodeJS process. For this we need the full path to the native module. We use a library called bindings to find the correct path to the native DLL.

Webpack while bundling changes those expectations (namely, the initialization code and package.json are located in the directory)

I'll take a look at the module loading code and see if it can be fixed.

@nukeop , As I wrote above, we need the package.json to locate the native counterpart to this extension.

So any bundler will break this functionality.

If you are using webpack, ignore this module using IgnorePlugin or Externals . I recommend the later.

Yep, you are 100% correct. I made the comment above so that I'll be able to find this thread the next day and share my solution to this problem for anyone visiting it in the future.

Here's the simplest solution if you want to bundle your server side code using webpack and use native modules:

  • Install webpack-node-externals
  • In your webpack config, add the following entries:
  • target: 'node'
  • externals: [nodeExternals()]
  • This solves the problem. If you find that there are modules that this solution excludes that should be bundled, add them to the whitelist of nodeExternals. For example lodash requires this.

    Hi @agathver, ignoring bcrypt (or all node_modules) was not a solution when you need to bundle your backend code. So it was a showstoper for me too.

    I switched to https://github.com/dcodeIO/bcrypt.js#readme to solve the bundle problem.

    Hi everyone, my use case involve an offline installation with an RPM package, so bundling node_modules was a no-go. Using webpack did the trick (I had to exclude tweak it a lot, like in https://github.com/ZenSoftware/bundled-nest/blob/master/webpack.config.js for my Nest application), but it works, with the exception of bcrypt. So I did like @florian-kittel , I switch to a pure JS implementation, to avoid deployment nightmare.

    If you have a recipe that can bundle bcrypt without hassle, I'll be glad to read it :)

    @Glandos If your deployment is an RPM, just copy the node_modules folder verbatim. You should not bundle NodeJS applications using something like webpack is an invitation to trouble. Not just bcrypt, bundling is not compatible with any module that uses native code, like pg or mongodb

    In your CI or build machine, perform a clean install using npm ci and then copy the resulting node_modules together with the code. I use this method to run code using bcrypt and other native modules in production where our standard deployment is with RPM for a fleet of VMs.

    472M node_modules/

    I always appreciate advice, but this is not applicable to me. I have 200 hundreds servers, some of them behind a small DSL line. Transferring half of a gigabyte of data for just 8MiB webpacked script is a complete waste of resource.
    Of course, under XZ (used with RPM packaging), this falls under 30MiB. But the compression takes a very long time, much longer than a 20s webpack call.

    By the way, I tried ncc ( https://github.com/vercel/ncc ) with great success: it detects the pattern of node-pre-gyp and does the compilation before bundling. Of course, in the end, you have a binary that must be compatible with the Node.js installation on your target node, but it is completely self-contained.