systemjs / builder

SystemJS build tool
MIT License
465 stars 122 forks source link

How to overwrite path to jspm_packages when running builder.buildStatic() #404

Closed dmbrowne closed 8 years ago

dmbrowne commented 8 years ago

Is it possible to override the path to /jspm_packages bundling a module into a self contained bundle, how?

To explain, I'm building a quick isomorphic react project in express with jspm handling the module requires in the browser. I have managed to get everything working perfectly for my sandbox, however when I want to bundle it up, I'm facing an error: systemjs-builder tells me it can't find file:///jspm_packages/github/floatdrop/plugin-jsx@1.1.0.js

my project structure is something like this:

jspm-iso-react
    |- dist/
    |   |- app/
    |   |   |- <reactComponents>
    |   |- js/
    |   |   |- appBootstrap.js
    |   |   |- systemJsConfig.js
    |- jspm_packages/
    |- node_modules/
    |- expressRouteHandlers/
    |- app.js
    |- gulpfile.js
    |- package.json

I'm Using express static folders, so jspm-iso-react/jspm_packages is mounted to jspm-iso-react/dist/jspm_packages in the browser. There lies my problem, because when I run builder.buildStatic('./dist/javascripts/appBootstrap.js', './dist/javascripts/bundle.js') from the gulpfile.js in the root; 'systemjs-builder' cannot find the path to /jspm_packages.

How do explicitly tell systemJsBuilder where to locate the jspm_packages directory?

guybedford commented 8 years ago

You could manually configure the paths for the endpoints here via something like:

builder.config({
  paths: {
    'npm:*': './jspm_packages/npm/*',
    'github:*': './jspm_packages/github/*'
  }
});

Let me know if that helps.

dmbrowne commented 8 years ago

Thanks that worked, but there is a ENOENT error now. The package that it couldn't find before /jspm_packages/github/floatdrop/plugin-jsx@1.1.0/jsx.js it is now finding correctly but that file has a require('react-tools') statement which is can't find Error: ENOENT: no such file or directory, open '/react-tools.js'. But my systemJsConfig.js is referencing the package properly so it seems like systemBuilder is ignoring it?

System.config({
  baseURL: "/",
  defaultJSExtensions: true,
  transpiler: "babel",
  babelOptions: {
    "blacklist": [],
    "presets": ["react", "es2015"],
    "stage": 0,
    "optional": [
      "runtime"
    ]
  },
  paths: {
    "github:*": "/jspm_packages/github/*",
    "npm:*": "/jspm_packages/npm/*"
  },
  packages: {
    "app": {
      "defaultExtension": false,
      "format": "cjs",
      "meta": {
        "*.jsx": {
          "loader": "jsx"
        }
      }
    }
  },
  meta: {
    "app/*": {
      "deps": [
        "/app/views/layout.jsx"
      ]
    }
  },
  map: {
    "babel": "npm:babel-core@5.8.34",
    "babel-runtime": "npm:babel-runtime@5.8.34",
    "core-js": "npm:core-js@1.2.6",
    "jsx": "github:floatdrop/plugin-jsx@1.1.0",
    "react": "npm:react@0.14.2",
    "react-engine": "npm:react-engine@2.6.0",
    "react-router": "npm:react-router@1.0.0",
    "github:floatdrop/plugin-jsx@1.1.0": {
      "react-tools": "npm:react-tools@0.13.3"
    },
    "npm:react-tools@0.13.3": {
      "buffer": "github:jspm/nodelibs-buffer@0.1.0",
      "commoner": "npm:commoner@0.10.4",
      "jstransform": "npm:jstransform@10.1.0",
      "process": "github:jspm/nodelibs-process@0.1.2"
    },
    "npm:react@0.14.2": {
      "envify": "npm:envify@3.4.0",
      "fbjs": "npm:fbjs@0.3.2",
      "process": "github:jspm/nodelibs-process@0.1.2"
    }
});
dmbrowne commented 8 years ago

upon further investigation, it seems that all files that are required in jspm_packages are resolving to <project root>/<module_name>. why is that and how do I get it to use the Systen.config.paths configuration that I've provided?


I managed to fix the issue for that module. In my System.config I had the following:

map: {
    "github:floatdrop/plugin-jsx@1.1.0": {
      "react-tools": "npm:react-tools@0.13.3"
    },
    "npm:react-tools@0.13.3": {
      "buffer": "github:jspm/nodelibs-buffer@0.1.0",
      "commoner": "npm:commoner@0.10.4",
      "jstransform": "npm:jstransform@10.1.0",
      "process": "github:jspm/nodelibs-process@0.1.2"
    }
}

and jspm_packages/github/plugin-jsx@1.1.0/jsx.js could not locate require('react-tools'). To fix it, I simply ran jspm install npm:react-tools, which automatically added "react-tools": "npm:react-tools@0.13.3" to the System.config() file. it now works and can find the react-tools module.

But this is an issue because I now have to run jspm install for all the required modules in third party packages. Am I missing something? is there another way to go about this?

dmbrowne commented 8 years ago

I managed to fix this with a hack. Basically looped through all the dependencies of the required modules and added them to the map property of the config:

const _               = require('lodash');
const systemJsConfig  = require('./dist/javascripts/config.js');

gulp.task('build', () => {
    var builder = new systemJsBuilder({baseURL: './dist'})
    builder
        .loadConfig('./dist/javascripts/config.js')
        .then(() => {
            let configMapAddition = _.chain(builder.loader.packages)
                .map(
                    (pckgMap) => { return pckgMap.map })
                .reduce(
                    (result, currentPckgMap) => {
                        for (var pckgMapKey in currentPckgMap) {
                            result[pckgMapKey] = currentPckgMap[pckgMapKey];
                        }
                        return result;
                    },
                    {})
                .value();

            configMapAddition.node_modules = './node_modules';

            builder.config({
                map: configMapAddition,
                packages: systemJsConfig.packages,
                paths: {
                    'app/*': './dist/app/*',
                    'npm:*': './jspm_packages/npm/*',
                    'github:*': './jspm_packages/github/*'
                }
            })

            builder.buildStatic('./dist/javascripts/bootstrap.js', './dist/javascripts/bundle.js')
        })
})

Not the best solution, but works.