javascriptnpmrendernpm-buildrender.com

How can I create a build from a JavaScript file based on node modules?


I created a new node project using

npm init
npm install apollo-server

I then added a index.js file with the following code:

const { ApolloServer, gql } = require('apollo-server');

const typeDefs = gql`
  type Query {
    hello: String
  }
`;

const server = new ApolloServer({
  typeDefs,
  mocks: true,
});

server.listen().then(({ url }) => {
  console.log(`🚀 Server ready at ${url}`)
});

While I can run this with node index.js, how could I actually create a build from my index.js so it doesn't directly need the modules during runtime? (goal: deploy it on platforms like e.g. render.com)


Solution

  • It sounds like you want to create a single executable artifact which requires no server-side configuration or setup to run.

    There are a few options for this. You're probably looking for a Javascript bundler, like Rollup, Parcel or Webpack. Webpack is the most widely used, but also generally the most difficult to configure.

    Using bundlers

    Parcel

    Install Parcel with npm i -g parcel, then, add this to your package.json:

      "main": "dist/index.js",
      "targets": {
        "main": {
          "includeNodeModules": true
        },
      },
    

    Then run parcel build index.js. That's it!

    I've added a simple demo on GitHub.

    Webpack

    There are a number of great answers on this SO question.

    Bundler caveats

    Many node packages come with binary/native addons. For example, Cypress downloads and installs a browser. Any package which uses native addons will not work with a bundler, as the bundler is unable to add the binary files. These packages will still need to be installed.

    Another option: building a binary

    In the processes above, your output artifact is a single Javascript file. Instead of a Javascript file, you could also produce a binary file and thus alleviate the need to install the Node runtime. Check out pkg to do this. While pkg is a fairly mature product, this is generally still considered an experimental technology, so perhaps not suited for a production environment. On the other hand, you shouldn't run into any problems with packages that include native addons. Read the documentation to see if it's appropriate for your use case.