evshiron / nwjs-builder

https://www.npmjs.com/package/nwjs-builder
76 stars 12 forks source link

Including node_modules (or other folders/files) in built app. #20

Closed orther closed 8 years ago

orther commented 8 years ago

I need to include a node module in the built app and I am not sure if this is supported with nwjs-builder. The specific module I need to include is auto-launch.

Does anyone have a suggestion(s) for handling this situation when using nwjs-builder? I suppose I could manually copy over the ./node_modules/auto-launch into my srcDir before running nwjs-builder build command.


For reference I solved this with nw-builder using an array in the files param like so:

        const nw = new nwBuilder({
            files: [
                `${srcDir}/**/**`,
                './node_modules/auto-launch/**/**',
            ],
            version: '0.12.3',
            buildDir: destDir,
            platforms: ['osx64', 'win32'],
            macIcns: `${iconsDir}/app.icns`,
            winIco: `${iconsDir}/app.ico`,
        });

This essentially this copied the ./node_modules/auto-launch folder into app.nw.

orther commented 8 years ago

For reference here is a chunk of code showing how I am building my app with nwjs-builder:

const NWB = require('nwjs-builder');

const buildOpts = {
    version: '0.14.5-sdk', // TODO (orther) test if we can remove this
    platforms: 'win32,osx64',
    outputDir: destDir,
    withFfmpeg: true,
    sideBySide: true,
    production: true,
    // TODO (orther) get OSX icons working before release
    // macIcns: `${iconsDir}/app.icns`,
    winIco: `${iconsDir}/app.ico`,
};

NWB.commands.nwbuild(srcDir, buildOpts, (err) => {
    if(err) throw err;
    cb();
});

NOTE: this is copied from a gulp task so ignore variables/functions being used that aren't defined or obviously global

evshiron commented 8 years ago

Try setting production to false. The --production option means to ignore the original node_modules and call npm install for a fresh installation. In my opinion it's not a good idea to include not installable modules directly in node_modules, although it does give some convenience. Even using a GitHub repo (like nwjs-builder itself) will be more acceptable. Currently nwjs-builder only copies files from path. If there is a need to copy files from other directories, tell me and I will add it in the next few days.

orther commented 8 years ago

Being able to copy files using glob format (e.g. foo/*.js, !foo/bad.js) at nwbuild time would be extremely useful for me. The truth is that I could add an extra build step that handles this but I think including this functionality into nwjs-builder makes sense.

Feel free to ignore the following explanation of why I need this feature. I'm including it in case anyone is curious why I need to copy in node modules to my app build.

_The need to copy in ./node_module/auto-launch to the build app was due to us needing to use global.require to load the auto-launch module. Using require (which resolves at build time) cause problems when running the built app on platforms different than the platform used to build it (e.g. running app on Windows after building it on OSX). Using global.require to load auto-launch was failing after installing our built app because the module file's weren't there. I found the solution of adding the nodemodule itself to the files param w/ nw-builder here: Teamwork/node-auto-launch#12

evshiron commented 8 years ago

I am thinking about how to implement this. The command line option I am going to add is -i, --include <SRC>[:DEST] and we can use it multiple times. SRC is a glob string and DEST is the relative path to the build directory, which will be converted to an array like [[src, dest], ...]. If I implement it like cp -r, things should be simple enough. For example, cp -r a/xxx b/ will copy a/xxx to b/xxx. But with a glob string, what I receive is a list of files, and If I want the relative path, I need to find the source root by something like var sourceRoot = path.resolve(src.split('*')[0]), and var relativeFiles = files.map((file) => path.resolve(file).split(sourceRoot)[1]). Thought it's not so elegant though. Any ideas?

evshiron commented 8 years ago

Feature added. Please upgrade to nwjs-builder 1.9.0. See also test-module.js.

orther commented 8 years ago

Wow awesome. I will be testing this later today. Thanks again for all your great work.

orther commented 8 years ago

Upgraded to nwjs-builder@1.9.1 and this feature is working perfectly so I am closing this issue.

For reference here is what my nwjs-builder code to replace the above nw-builder code example using this new feature to include auto-launch module in app:

const buildOpts = {
    version: '0.14.5-sdk',
    platforms: 'win32,osx64',
    outputDir: destDir,
    withFfmpeg: true,
    sideBySide: false,
    production: true,
    macIcns: `${iconsDir}/app.icns`,
    winIco: `${iconsDir}/app.ico`,
    include: [
        ['./', 'node_modules/applescript/**/**', './'],
        ['./', 'node_modules/auto-launch/**/**', './'],
        ['./', 'node_modules/winreg/**/**', './'],
    ],
};

function nwbuild(cb) {
    NWB.commands.nwbuild(srcDir, buildOpts, (err) => {
        if(err) throw err;
        cb();
    });
}
orther commented 8 years ago

I'd like to note that I now realize for global.require'd node modules you can add them as dependencies in your nwjs app manifest rather than having to include them manually w/ nwbuild like I am in the above example. This has the advantage of not needing to manually list nested deps. So instead of including auto-launch in my main project package.json I would include it in my nwjs app manifest file like below and remove the include section from buildOpts.

{
  "name": "yourapp-name",
  "description": "Your app description",
  "version": "0.0.1",
  "main": "index.html",
  "chromium-args": "--unlimited-storage --enable-usermedia-screen-capturing --allow-insecure-websocket-from-https-origin --allow-running-insecure-content --remember-cert-error-decisions --ignore-certificate-errors --ignore-urlfetcher-cert-requests",
  "window": {
    "icon": "icons/appIcon.png",
    "width": 350,
    "height": 600,
    "x": 0
  },
  "dependencies": {
    "auto-launch": "^1.1.1"
  },
  "webkit": {
    "plugin": true
  }
}