Can browserify resolve require calls in methods - browserify

I have
A package with a plugin system. Each plugin is a package
One can load a plugin by alling the method use and pass the plugins export as argument:
package = require('thePackage').use( require('thePlugin'), require('anotherPlugin'));
i want
If the argument of use is a string use should require the module.
package = require('thePackage').use('thePlugin','anotherPlugin')
the question
Can browserify resolve this usage of require?
I am not sure if browserify just looks for reqire calls in the top levl or if actualy eveluat the code.

Browserify processes only require() calls with literals, i.e. require('theplugin');
It will not include modules that can be required with something like:
function use(moduleName) {
require(moduleName);
}
use("someModule");
You can see it in the code, by looking at module-deps (which is the module for scanning the modules) which calls node-detective, which by default returns only literals (strings) for require() calls.
You can still achieve what you want, and use the require() with parameters inside your functions for plugins, but then you will have to be more explicit with what you include in your browserified package. Browserify will not traverse through those plugin modules if it won't see a literal require, so you need to --require them manually.
for example browserify --require ./src/plugins/plugin.js
Module loading resolution (i.e. argument for require()) might not work the same under node.js and in a browserified environment, so be careful if you're doing some clever module name resolution in your use() function.

Related

Is there a way to include non-exporting js library into vue cli project?

For the past 2 days I've been trying to include a non-exporting js library into my vue project and it seems to fail every time. The closest I've got to a working thing is with import *. It recognizes the commands in the library, but when I try to use them, it gives me an error that says:
the namespace is undefined
My question is - what is the best way to include a non-exporting (legacy) js library in a vue project?
import * as test from "library.js"
The webpack compiler can understand modules written as ES2015
modules, CommonJS or AMD. However, some third party libraries may
expect global dependencies (e.g. $ for jQuery). The libraries
might also create globals which need to be exported. These "broken
modules" are one instance where shimming comes into play.
Reference.
import './path/to/library.js'

What is the difference between plugins and dependencies in the Vue.js UI?

When using the ui you have the option of installing dependencies and plugins.
I am confused about the difference between both of these.
For instance, I can install axios as a dependency and a plugin.
Do I need to do both? Why do one over the other?
My current understanding is that dependency is just that, it adds a package to your project while a plugin will add configuration as well.
Am I correct in thinking that?
A plugin is exactly what you described. It 'plugs into' another piece of software and adds functionality. A dependency on the other hand means that your software simply depends on something to function correctly - usually code.
In your axios example:
The axios plugin installs another prototype property on your Vue instance (this.$axios.. or whatever it is called) so it definitely adds a feature to Vue.
You could also only use Axios by itself and import it in the files you need
import axios from 'axios'. You don't add any feature to Vue itself - you just use another software within your app. Axios here is a dependency.
I will probably not be completely correct, but my understanding is
Plugins vs Dependencies
Command line
dependencies are installed via the command line as npm install <name> or npm install --save <name> to add the dependency to package.json
plugins are installed via the command line as vue add #scope/vue-cli-plugin-<name> or with the shorthand vue add #scope/<name>
Installation
dependencies are placed into your projects node_modules folder
plugins will invoke the generator.js script of the plugin being installed. This generator.js may add dependencies to package.json, add import statements to files in your project, add/alter existing components, or any of the various things listed under the generator api docs
Usage
dependencies will need to be imported into any file you use them in, or imported globally, before they are able to be used
plugins often will have already set up global imports, making them available in every file. Plugins will also often add additional scripts to package.json (which show up as tasks in the vue ui)

How to use browserify standalone option

I'm trying to create a standalone library that can be used as global variable, amd or commonjs module.
But after compiling it with browserify with standalone option, I can't include it in a next build as a compiled library because of the browserify error
Error: Cannot find module './dependency'
How to handle this problem.
All source code that i use can be found here: https://github.com/paveltyavin/double-browserify
Ok, the problem described in this github issue and in this question.
TLDR: use derequire.
Browserify parses compiled code and tries to make bundle everytime it reads function require . Minification (uglify) can be a nice workaround to handle the problem.

Browserify - How to include non-public purchased third party scripts

I am new to browserify and its usage is not completely clear to me although the benefits seem to be compelling.
I have a couple of questions and was hoping someone could clarify.
I've seen blog posts about using browserify-shim in the package.json to include third party libraries like jquery and bootstrap. I've also seen posts where tools like gulp are used generate the bundle file. I can't seem to find a good answer on why browserify-shim is required if tools like gulp are able to automate the process. Can someone please shed some light? Why is browserify-shim even required? I feel the gulp solution is a little cleaner although a little more involved. It won't pollute package.json with browserify specific stuff that is a build thing and therefore goes together with gulp (just my personal opinion)
How does one deal with third party libraries that are not in npm and also not public? For example, we purchase a script from a third party. That script is not any common js, but is a regular js file with some dependencies (example, on jquery and underscore).
Browserify lets you take the world of Node and bundle it up for delivery to a browser. It understands Node modules, which define dependencies via CommonJS require statements.
But what if you have some JS code or library that is not defined as a Node module and does not support CommonJS? Enter browserify-shim. It provides a shim wrapper around any script, like your private third party script, so that it can be defined as and used as a Node module that Browserify understands.
The use of browserify-shim is completely orthogonal to how you execute Browserify. There are basically two options there: A) Use Browserify's command line API or B) Use Browserify's JS API.
Using a build tool, like Gulp, implies the second option, since you'd use Browserify's JS API in your Gulp build script (i.e. gulpfile.js). A lot of people prefer the use of Gulp because it has a good ecosystem of plugins that allow you to do a lot more than just call Browserify (e.g. compile CoffeeScript, compile SASS, run JSHint, etc).
So, to answer your specific questions:
Browserify-shim is only required if you have JS code that is not written as a Node/CommonJS module that you need to bundle via Browserify. To do so, you will need to tell browserify-shim which files to shim as modules (and what dependencies they have) in package.json. Note that this is totally unrelated to Gulp; so you will need it whether you use Gulp or not.
What you describe is the perfect use-case of browserify-shim. Put your third party script(s) in your project, configure the files to be modules in package.json per b-shim's documentation, require them in your code, and execute Browserify to bundle them up with your code. You could also bundle them up separately, put them in their own project, etc - however you want to structure it.
A couple things to note:
You can shim just about any JS library this way.
Shimming a JS library to be a Node module changes global scope to be private scope. Hopefully everything in the library is namespaced so that all of its functionality can be exported as a single module, but if it's not, you might have to modify the shimmed code to explicitly attach things to window (which is easy but not recommended) or split the code up into separate files/modules.
Both Browserify and Gulp use streams in their JS API, but Browserify uses native Node streams while Gulp uses Vinyl streams. Since they don't play well together, you'll probably have to use vinyl-source-stream to adapt Gulp to Browserify (e.g. for renaming files in a Browserify pipeline), or use vinyl-transform to adapt Browserify to Gulp (e.g. wrap a Browserify stream for use in a Gulp pipeline).

Share module between client and server with TypeScript

I want to write a portable module that can be reused between the node.js server and the browser.
It's the modularization thing that's stopping me atm. I'm reading http://caolanmcmahon.com/posts/writing_for_node_and_the_browser/ and it looks straightforward, however is getting tsc to generate something like that possible?
If you write your TypeScript in the CommonJS / AMD style (i.e. each file is a module) you can ask the compiler to output either CommonJS (for nodejs server) and AMD (for the browser, using requires.js).
So your module file would look like this (with no module declaration)
MyModule.ts
exports class MyClass {
constructor (private id: number) {
}
// ... etc
}
And you would use the following compiler commands to get the output...
For nodejs OR browsers (recommended)
tsc --module umd MyModule.ts
For nodejs
tsc --module commonjs MyModule.ts
For the browser (using requires.js)
tsc --module amd MyModule.ts
The only difference in compiled output is that the server code will use the CommonJS import statements to load modules and the browser code will call requires.