admin管理员组

文章数量:1352788

I'm trying to package a node app as an exe using pkg, and I'd like to use ES6 imports.

I have something like this in my src/app.js:

import express from 'express'
const app = express()

const eco = (req, res) => {
  const { method, url, headers, query } = req
  res.json({ method, url, headers, query })
}

app.all('/', eco)

app.listen(3000, () => console.log(`listening on http://localhost:3000`))

in my package.json I have:

{
  "name": "pkg-test",
  "version": "1.0.0",
  "description": "",
  "main": "src/app.js",
  "type": "module",
  "type": "module",
  "scripts": {
"build": "pkg --targets=node12-win-x64 --output=iisnode-pkg.exe --options experimental-modules src/app.js",
    "start": "node --experimental-modules src/app.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1"
  },
  "devDependencies": {
    "pkg": "^4.4.0"
  }

}

npm start works fine

$ npm start

> [email protected] start C:\data\devel\apps\tmp\iisnode-pkg
> node --experimental-modules src/app.js

(node:10668) ExperimentalWarning: The ESM module loader is experimental.
wele to iisnode-pkg
iisnode-pkg listening on http://localhost:3000

but npm run build gives a waning and then running the exe throws an error:

>npm run build

> [email protected] build C:\data\devel\apps\tmp\iisnode-pkg
> pkg --targets=node12-win-x64 --output=iisnode-pkg.exe src/app.js --config package.json

> [email protected]
> Warning Failed to make bytecode node12-x64 for file C:\snapshot\iisnode-pkg\src\app.js
>iisnode-pkg.exe
C:\snapshot\iisnode-pkg\src\app.js:2
import express from 'express'
       ^^^^^^^

SyntaxError: Unexpected identifier
    at Module._pile (internal/modules/cjs/loader.js:701:23)
    at Module._pile (pkg/prelude/bootstrap.js:1268:32)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:768:10)
    at Module.load (internal/modules/cjs/loader.js:626:32)
    at Function.Module._load (internal/modules/cjs/loader.js:553:12)
    at Function.Module.runMain (pkg/prelude/bootstrap.js:1316:12)
    at internal/main/run_main_module.js:17:11

It seems like the --options experimental-modules parameter from the build script in package.json is not beign taken into account.

Any idea how can I use ES6 module imports from a node app packaged with pkg?

I'm trying to package a node app as an exe using pkg, and I'd like to use ES6 imports.

I have something like this in my src/app.js:

import express from 'express'
const app = express()

const eco = (req, res) => {
  const { method, url, headers, query } = req
  res.json({ method, url, headers, query })
}

app.all('/', eco)

app.listen(3000, () => console.log(`listening on http://localhost:3000`))

in my package.json I have:

{
  "name": "pkg-test",
  "version": "1.0.0",
  "description": "",
  "main": "src/app.js",
  "type": "module",
  "type": "module",
  "scripts": {
"build": "pkg --targets=node12-win-x64 --output=iisnode-pkg.exe --options experimental-modules src/app.js",
    "start": "node --experimental-modules src/app.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1"
  },
  "devDependencies": {
    "pkg": "^4.4.0"
  }

}

npm start works fine

$ npm start

> [email protected] start C:\data\devel\apps\tmp\iisnode-pkg
> node --experimental-modules src/app.js

(node:10668) ExperimentalWarning: The ESM module loader is experimental.
wele to iisnode-pkg
iisnode-pkg listening on http://localhost:3000

but npm run build gives a waning and then running the exe throws an error:

>npm run build

> [email protected] build C:\data\devel\apps\tmp\iisnode-pkg
> pkg --targets=node12-win-x64 --output=iisnode-pkg.exe src/app.js --config package.json

> [email protected]
> Warning Failed to make bytecode node12-x64 for file C:\snapshot\iisnode-pkg\src\app.js
>iisnode-pkg.exe
C:\snapshot\iisnode-pkg\src\app.js:2
import express from 'express'
       ^^^^^^^

SyntaxError: Unexpected identifier
    at Module._pile (internal/modules/cjs/loader.js:701:23)
    at Module._pile (pkg/prelude/bootstrap.js:1268:32)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:768:10)
    at Module.load (internal/modules/cjs/loader.js:626:32)
    at Function.Module._load (internal/modules/cjs/loader.js:553:12)
    at Function.Module.runMain (pkg/prelude/bootstrap.js:1316:12)
    at internal/main/run_main_module.js:17:11

It seems like the --options experimental-modules parameter from the build script in package.json is not beign taken into account.

Any idea how can I use ES6 module imports from a node app packaged with pkg?

Share Improve this question edited Oct 16, 2019 at 8:57 opensas asked Oct 15, 2019 at 10:19 opensasopensas 63.7k90 gold badges265 silver badges415 bronze badges 2
  • github./vercel/pkg/issues/1291 – danielnixon Commented Dec 27, 2021 at 7:53
  • See my answer here: stackoverflow./a/75019478/10030693 – Gilbert Commented Jan 5, 2023 at 13:54
Add a ment  | 

3 Answers 3

Reset to default 6

I'll post an update if I find a resolution but this no longer seems possible.

ESM modules are no longer experimental, they are a core part of Node and the remended convention to use.

Given a simple test, the current pkg generates a warning that results in ESM module files being skipped with this error, so at runtime the module cannot be loaded. I am not sure when this broke, but I have posted a simple reproduction of the problem here: https://github./appurist/pkgtest/

I've also added a ment on the (closed) GitHub issue here: https://github./vercel/pkg/issues/641#issuement-870013906

There doesn't appear to be any workaround as the problem seems to be in pkg itself.

You will have to first convert the ESM to Commonjs. You can use babel/preset-env for this. Then afterwards use pkg to build the exe from the generated Commonjs.

Here is a snippet from my package.json.

   ...
  "main": "index.js",
  "type": "module",
  "scripts": {
    "convert": "babel src -d lib",
    "test": "jest",
    "start": "node src/index.js",
    "dev": "nodemon src/index.js",
    "build": "npm run convert && pkg ./lib/index.js --target node16-win-x64 -o build/SGMS-API.exe"
  },
 "devDependencies": {
    "@babel/cli": "^7.18.10",
    "@babel/core": "^7.18.10",
    "@babel/preset-env": "^7.18.10",
    "@jest/globals": "^28.1.3",
    "pkg": "^5.8.0"
  }

And here is my babel.config.json

{
    "presets": ["@babel/preset-env"]
}

This is a good starting point for babel: https://babeljs.io/setup#installation

Make sure you're running a pretty recent version of Node. The implementation of ESM in Node.js changed in version 12.0.0. "type": "module" wasn't supported in 10.x.

You need to add options to the pkg configuration. So, in package.json:

"pkg": {
    "options": ["experimental-modules"]
}

Node documentation: https://nodejs/api/esm.html

本文标签: javascriptuse ES6 import modules with pkgStack Overflow