Browserify multiple standalone modules that shares or requiring same file - browserify

I am trying to browserify a set of models/classes which are in separate files and use them as a library with the standalone flag.
I have noticed that some of these models requires the same base class(es) and gets duplicated with browersify on output.
Example:
Foo.js
var Base = require('base.js')
class Foo extends Base ...
Bar.js
var Base = require('base.js')
class Foo extends Base ...
Browserify each file..
browserify foo.js --standalone Foo > dist/foo.js
browserify bar.js --standalone Bar > dist/bar.js
Inside foo.js and bar.js has the base class defined. It works without issues, but I'm curious to know if there is an efficient way to browserify multiple standalone files that some of them requires the same file.
Is it possible to browserify multiple standalone files but share the same base class?

Related

Don't bundle process.env variables, webpack/vue.js

I have a Vue.js application that imports private npm packages that are Vue.js libraries:
// Vue.js app
import { someComponent } from '#private-npm/some-library';
The someComponent has some code that looks as such:
// someComponent
const username = process.env.USERNAME;
When I build some-library, so that I can publish it to my private repo, it writes the process environment variables in plain text inside the bundle file.
So my concerns:
Even though my npm is private, I feels like bad practice to have my environment variables written to the module which someone can install and view inside node_modules.
I need to be able to build the Vue.js app that uses the library with different environment variables
So, in summary, I need my bundled library to not import the real value of the process environment variable and instead leave it as process.env.USERNAME so when the Vue.js app builds it can dynamically change that variable via a .env.

How to publish a vue js plugin that modifies an existing plugin

I am trying to create a plugin that utilizes components from another Vuejs plugin (Vuetify). Basically, I have some common components I want to share across multiple applications with our company.
I thought it would just be a matter of:
Create a github repo for the shared components
Author the plugin
Reference the repo in consuming apps via npm install
Here is the gist of the plugin:
// src/index.js <-- package.json/main is set to "src"
import MyComponent from "./MyComponent.vue";
import * as api from "./api";
export default function install(Vue) {
Vue.component("myComponent", MyComponent );
Vue.prototype.$myApi = api;
}
At the moment, the behavior I'm seeing is:
GOOD
plugin install function is being executed
functions from api attached to Vue.prototype are available in app components
my-component is available in the app and renders markup
BAD
$myApi and Vuetify components are not available in an application instance of of my-component
If I copy the same files into the app and change my import, all works as expected. So, I now wonder if I'm missing something regarding sharing code via external modules.
I've tried these alternatives with the same issue:
use npm link to link the plugin module to the app
manually, use mklink (Windows sym link) to link plugin module to node_modules in the app folder
use a long relative path reference to the plugin module: import MyPlugin from "../../../my-plugin"
I've put this issue off for a while, but for anyone wondering, the issue is with using Single File Components and webpack not compiling those in external modules.
The 2 options I have are:
Don't use Single File Components. I.e.: Just use .js instead of .vue. I've seen some libs like Vuetify.js take this approach
Compile the .vue files in the library module and include them in the source such as ./dist folder.

How to create standalone browserify bundle exporting directly to window?

I want to create a standalone browserify bundle which attaches the exported objects directly to the window object, not nested under a wrapper object attached to window.
Doing this, browserify ignores the window:
browserify main.js --standalone window > bundle.js
The main.js file looks like this:
var ModuleA = require('./module-a.js');
var ModuleB = require('./module-b.js');
module.exports = {
ModuleA: ModuleA,
ModuleB: ModuleB
}
I want both modules exposed directly in the global namespace: window.ModuleA and window.ModuleB.
The documentation doesn't provide an obvious solution.
Can you help?
This should work:
global.ModuleA = require('./module-a.js');
global.ModuleB = require('./module-b.js');
You could also use window instead of global.
The argument for --standalone is supposed to be the name of the global variable that you want to assign to the module. In your example, you are using "window", which will probably cause some strange things to happen in your site.
Instead of forcing the modules into the global scope (some devs might not want them there due to conflicts), do something like this:
browserify main.js --standalone TheModulesAB > bundle.js
Then you will be able to load bundle.js and reference your modules like so:
TheModulesAB.A //module-a.js
TheModulesAB.B //module-b.js

How does browserify bundle a universal module

I know browserify can consume UMD modules by means of transforms, but when I want to build a lib using browserify, how can I build an UMD module? Is there any transform I can use?
If you want to build a UMD module with browserify use the standalone option. Like:
browserify('./entry.js', {
standalone: 'moduleName',
})
From the CLI: browserify -s NameOfModule
This creates a standalone module exposed under the name of your choosing.
Utilize by loading the output file in a browser and access via window.NameOfModule, or see RequireJS docs on how to use it that way.

How to use browserify with non-npm libraries?

According to http://www.slant.co/topics/1089/viewpoints/1/~what-are-the-best-client-side-javascript-module-loaders~browserify#9 one of the downside of using Browserify is that:
Not all javascript libraries have an npm version
While it's not too hard to create npm package for an existing library, it means maintaining it when the library updates. While most libraries are now on npm, many client side specific libraries are not.
I don't have any experience with npm aside from knowing how to install an existing module. In light of that, what is the easiest/best way to browserify with client-side non-npm libraries?
Is there a way for me to declare a local Javascript file as a dependency, instead of looking it up through npm?
You can use local modules without problems by two ways:
1.Use a relative path to a module in require:
var myModule = require('../js/my-module');
2.Use a module name, but before, you should to add it to browser property in package.json:
package.json:
...
browser: {
my-module: './js/my-module.js'
}
app.js:
var myModule = require('my-module');
Some packages are packages with bower, these can be used with browserify by using the debowerify plugin.
For non-versioned things you can copy them to a lib directory in your project or add them as a git submodule and then configure browserify so that it can find things there too.