vercel / pkg

Package your Node.js project into an executable
https://npmjs.com/pkg
MIT License
24.32k stars 1.01k forks source link

Packaging frontend assets? #245

Closed geekyme closed 3 years ago

geekyme commented 7 years ago

I have frontend (build/ folder) and node api code in the same repo, the structure looks like this:

build/
api/
server.js

server.js contains a piece of code that will serve the assets in build/

app.use(express.static('build')) 

I'm using pkg to build an executable (app.exe).

Expected result: run app.exe, and server serves the assets in build/. Actual result: run app.exe, but server complains that it cannot find the build assets. I had expected pkg to somehow wrap the build/ folder into the executable.

Am I missing something or doing something wrongly?

mika-fischer commented 7 years ago

See https://github.com/zeit/pkg#detecting-assets-in-source-code and https://github.com/zeit/pkg#assets

Basically, you need to use path.join(__dirname, 'build') or something like that, so that pkg can rewrite it to the internal snapshot filesystem. And then you might also need to actually tell pkg to include the stuff in build in the snapshot filesystem.

geekyme commented 7 years ago

And then you might also need to actually tell pkg to include the stuff in build in the snapshot filesystem.

How do I do this?

mika-fischer commented 7 years ago

See https://github.com/zeit/pkg#config and https://github.com/zeit/pkg#assets

nicolamontini commented 7 years ago

I have the same issue. Can you be a bit more precise about the solution? When i execute the pkg script with the --debug flag I can see the files specified as assets are added correctly, but how can I access them from a browser? Let's say I have a file in this path: "project_root_folder/static_resources/dist/img.png", which is added as an asset, and my server is listening on "localhost:2017". What is the URL I have to digit in my browser to access to that file?

michaeljota commented 6 years ago

I'm having this same problem. I'm using server to do a small API Rest server, but when I bundle it with pkg, I can't find the views folder, either the assets folder. Where are this getting placed inside the bundle?

ifree92 commented 6 years ago

The same problem. I just try to use recommended approach with path.join(__dirname, '...') but this doesn't works. Also I tried param option pkg bin/www.js --assets "views/**/*" and have the same fails.

$ pkg --version
4.3.0-beta.1

ADDED:

Seems all works. I just used this config https://github.com/zeit/pkg/blob/master/examples/express/package.json as example to configure my project. The "assets" field should be an array, not a string in my case.

michaeljota commented 6 years ago

I have used assets as an array, but it does not work for me.

mordom0404 commented 6 years ago

I have the same issue but I finally solve it. I created an express server and I pointed the static folder to "dist",and then I met the same issue as above. app.use(express.static("dist")); then I replace dist with path.join(__dirname, 'dist') then I successfully solve the problem.

this is my package.json file

{
// other options
    "bin": "service.js",//the entrance file
    "pkg": {
        "assets": [
            "dist/**/*"
        ]
    }
}

this is my service.js file

const express = require('express');
const app = express();
const path = require('path');

app.use(express.static(path.join(__dirname, 'dist')));//I solve the problem at this place

var server = app.listen(8081, function () {
    var host = server.address().address
    var port = server.address().port
    console.log(`server start successfully on http://${host}:${port}`)
})
szaffarano commented 6 years ago

Hi, I have a project structure like that:

frontend # a vue application
backend # a nodejs+express application
backend/app.js # entry point 
backend/public/favicon.ico # favicon

When I configure express, I add a static path:

app.use(express.static(path.join(__dirname, 'public')));

The build process consists in:

  1. Build the VueJS application (with webpack, all inside frontend folder)
  2. Run pkg to build my nodejs app (inside backend folder)
  3. Assemble all the files: binary produced by pkg plus static files produced by the VueJS build process

The problem is that I need that the pkg binary ignores the public folder because it will be exploded and not inside the internal snapshot filesystem. Is this possible? Or I should change my express configuration with something like:

app.use(express.static('public'));

Thank you

banjankri commented 6 years ago

In case more people run into this problem - I was struggling to get the snapshot to work due to preprocessing done with webpack. Basically it is mocking some of the node APIs by default together with __dirname. To prevent that from happening simply add node: false to your webpack config.

HassanHeydariNasab commented 5 years ago

I have the same issue but I finally solve it. I created an express server and I pointed the static folder to "dist",and then I met the same issue as above. app.use(express.static("dist")); then I replace dist with path.join(__dirname, 'dist') then I successfully solve the problem.

this is my package.json file

{
// other options
    "bin": "service.js",//the entrance file
    "pkg": {
        "assets": [
            "dist/**/*"
        ]
    }
}

this is my service.js file

const express = require('express');
const app = express();
const path = require('path');

app.use(express.static(path.join(__dirname, 'dist')));//I solve the problem at this place

var server = app.listen(8081, function () {
  var host = server.address().address
  var port = server.address().port
  console.log(`server start successfully on http://${host}:${port}`)
})

Also remember to tell pkg to use package.json: pkg . -t node8-linux-x64 instead of direct pointing to the app pkg app.js

PenguinOfTheSky commented 5 years ago

After multiple hours trying to get a simple hello world express app to work with this (serving static files) I'm forced to conclude that pkg doesn't actually work. at all.

app.use(express.static(path.join(__dirname, 'public'))); //fails. "pkg": { "scripts": [], "assets": [ "node_modules/**/*", "views/**/*", "public/**/*" ] },//fails

If, and at this point it seems seriously unlikely, pkg actually does function, a hello world example of a server would be helpful somewhere in the repo.

HassanHeydariNasab commented 5 years ago

After multiple hours trying to get a simple hello world express app to work with this (serving static files) I'm forced to conclude that pkg doesn't actually work. at all.

app.use(express.static(path.join(__dirname, 'public'))); //fails. "pkg": { "scripts": [], "assets": [ "node_modules/**/*", "views/**/*", "public/**/*" ] },//fails

If, and at this point it seems seriously unlikely, pkg actually does function, a hello world example of a server would be helpful somewhere in the repo.

Don't include node_modules as asset. it will be added automatically.

uds214125 commented 5 years ago

@HassanHeydariNasab same problem here too, can't able to serve dist code.

t133 commented 5 years ago

Hey , also faced same problem.. i wanted to include views folder in my binary. solved adding this :

 "pkg": {
        "assets": [
            "views/*"
        ]
    }

in main package.json file in my app's root folder.

danielj86 commented 5 years ago

I have finally managed to solve this issue by adding the above lines in package.json

"bin": "app.js", "pkg": { "assets": [ "client/*/" ] }

And then running

pkg package.json --debug >output.log

Appending debug output to a log file can help assure that the assets were added to the executable.

JahsonKim commented 3 years ago

I have followed all the above suggestions but still getting the same issue.

Error: Failed to lookup view "./user/Login" in views directory "/snapshot/web/src/views" at Function.render (/snapshot/web/node_modules/express/lib/application.js:580:17) at ServerResponse.render (/snapshot/web/node_modules/express/lib/response.js:1012:7) at /snapshot/web/src/WebAPI/WebRoutes/PublicHandler.js:0:0 at Layer.handle [as handle_request] (/snapshot/web/node_modules/express/lib/router/layer.js:95:5) at next (/snapshot/web/node_modules/express/lib/router/route.js:137:13) at Route.dispatch (/snapshot/web/node_modules/express/lib/router/route.js:112:3) at Layer.handle [as handle_request] (/snapshot/web/node_modules/express/lib/router/layer.js:95:5) at /snapshot/web/node_modules/express/lib/router/index.js:281:22 at Function.process_params (/snapshot/web/node_modules/express/lib/router/index.js:335:12) at next (/snapshot/web/node_modules/express/lib/router/index.js:275:10) at Function.handle (/snapshot/web/node_modules/express/lib/router/index.js:174:3) at router (/snapshot/web/node_modules/express/lib/router/index.js:47:12) at Layer.handle [as handle_request] (/snapshot/web/node_modules/express/lib/router/layer.js:95:5) at trim_prefix (/snapshot/web/node_modules/express/lib/router/index.js:317:13) at /snapshot/web/node_modules/express/lib/router/index.js:284:7 at Function.process_params (/snapshot/web/node_modules/express/lib/router/index.js:335:12)

neilveil commented 3 years ago

Basically, it works if we do something like this

{
  ..
  "bin": "index.js",
  "pkg": {
    "assets": ["dist/**/*"]
  },
  ..
}

in package.json

But why we can't set "--assets" directly from terminal?

github-actions[bot] commented 3 years ago

This issue is stale because it has been open 90 days with no activity. Remove the stale label or comment or this will be closed in 5 days. To ignore this issue entirely you can add the no-stale label

github-actions[bot] commented 3 years ago

This issue is now closed due to inactivity, you can of course reopen or reference this issue if you see fit.