I'm finding that it's a pain when moving files around and constantly having to rewrite the file include paths to be relative to their new folder.
I want to avoid this in my browserify code:
var View = require('../../../../base/view');
And do something more in line with requirejs where it knows my base path is js
:
var View = require('base/view');
Browserify works by specifying an entry point file and searching for all require() calls. Based on this search, Browserify generates a stream of concatenated JavaScript files that is written to a single bundle. js file. This output file can be referenced via a regular <script> tag in the browser.
RequireJS is a JavaScript file and module loader. It is optimized for in-browser use, but it can be used in other JavaScript environments, like Rhino and Node. Using a modular script loader like RequireJS will improve the speed and quality of your code. Get started then check out the API.
To use the require() statement, a module must be saved with . js extension as opposed to . mjs when the import() statement is used. ES modules can be loaded dynamically via the import() function unlike require().
It is possible to use require() on the client browser side. For example: var myClass = require('./js/myclass. js');
You should use the paths
option. It is not documented in browserify but in node-browser-resolve (used under the hood):
paths - require.paths array to use if nothing is found on the normal node_modules recursive walk
A great option here is to use the aliasify
plugin, available here. Then just add something like this to your package.json
, with all paths in the aliasify config being relative to the position of that file:
"browserify": {
"transform": [
"aliasify"
]
},
"aliasify": {
"aliases": {
"app": "./src/app",
"components": "./src/components",
"someAlias": "./src/app/some/path/to/a/place",
"foobar": "./go/to/a/module/named/foobar",
}
}
Then, in your files, just do:
var foobar = require("foobar");
var sampleComponent = require("components/someSample");
//My JS code
node_modules
You can put your application code (or a symlink to it, if your platform supports it) under node_modules
. E.g.:
node_modules/
+-- app/
+-- js/
+-- base/
+-- view.js
+-- a/
+-- b/
+-- c/
+-- somefile.js
// somefile.js
require("app/js/base/view");
However, there's an important caveat: this breaks application of transforms specified programmatically via the API, e.g:
browserify('app/entry.js')
.transform(es6ify)
In browserify there's a concept of "top-level" files that comes into play with transforms. That concept, and the behavior of transforms in general, is poorly explained in the browserify documentation. You can see some discussion of the issue here: substack/node-browserify#993
Another option is my pathmodify browserify plugin. This allows using non-relative paths and programmatic transforms. To enable browserifying code like:
var View = require('base/view');
You would do something like:
var pathmodify = require('pathmodify');
var opts = {mods: [
// Maps require() IDs beginning with "base/" to begin with
// "/somedir/js/base/"
pathmodify.mod.dir("base", "/somedir/js/base"),
]};
// Give browserify the real path to entry file(s).
// pathmodify will transform paths in require() calls.
browserify('./js/entry')
.plugin(pathmodify, opts)
.transform(es6ify)
.bundle()
...
Note that pathmodify will only solve the problem for browserify. If you need the paths like base/view
to also work in another context, like node, then if you have symlinks available you can combine the two. For example, symlink node_modules/base
to /somedir/js/base
, and also configure pathmodify as indicated and continue to point browserify to paths outside of node_modules
for entry files.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With