How to create standalone browserify bundle exporting directly to window? - browserify

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

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.

"require is not defined" in Vue.js

I have installed vue-star-rating module with npm. I want import this module in my JS file
var StarRating = require('vue-star-rating');
When I hover on 'vue-star-rating' shows full path to module and module also exists in noe_modules folder, but when I run my app in console I get a
ReferenceError: require is not defined
message. I have tried also other methods to import, but it still doesn't work.
import StarRating from 'vue-star-rating'
Also, you will need something like Webpack to compile and create the bundle properly. It will not work without a bundler.
Are you using a compiler to generate a bundle?
You can't reference modules this way as require doesn't exist on the client. You need to use something like fuse-box, webpack, etc. to properly handle the require function and include the modules you're referencing in your client bundle.

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.

Aurelia Element Loading Issues

Our environment has setup a private git repository and configured jspm to install packages from this repository. The repo has a .js, .html, and .css file. Jspm brings all the files down into a folder with #master appended to the name to reflect the branch and stores it all in the pre-configured jspm_packages location on my machine. It also adds a second #master.js file next to the folder with export statements inside (I didn't create this file myself).
These files represent custom elements I want to use in my aurelia application. There is a .js for the viewmodel and a .html for the view (and a .css file). When I go to use the custom element I get a 404, file not found, because system.js is looking for a #master.html file, which doesn't exist.
Jspm seems to be referencing the #master.js file in config.js and somehow that's assuming a #master.html file in Aurelia? Only a #master.js file was created when I installed the package using jspm. The original .html file does exist and lives inside the folder I mention above, but that #master.html file does not and I'm not sure 1) what that file would be for and 2) why it's being referenced. There no reference to #master.html in my code.
I'm not really even sure if this is a JSPM issue, Aurelia issue, System.js issue, or some combination of them?
Anyone else have a similar experience with these technologies?
Thanks,
Chris
Essentially, Aurelia believes you are importing your repo as a custom element, so when you are importing the #master.js it is looking for the matching "view" of what it assumes is a viewmodel.
It sounds like you need to structure your repository as a plugin. Add an index.js file at the top level and make that responsible for running the configure function, which should make the components you want global resources. Ensure your package.json points to your index.js as the 'main'. After that, you would need to add a .plugin('your-package-name') in the main.js file, just like any other plugin.
An example index.js is like so:
import {Options, GLOBAL_OPTIONS, DIRECTION} from './options';
import {Dragula} from './dragula';
import {moveBefore} from './move-before';
export {Dragula, Options, DIRECTION, moveBefore};
export function configure(config, callback) {
let defaults = new Options();
config.container.registerInstance(GLOBAL_OPTIONS, defaults);
if (callback !== undefined && typeof callback === 'function') {
callback(defaults);
}
config.globalResources(['./dragula-and-drop']);
}
(taken from here)

Browserify run a single file

I'm trying to build up an embeddable script that runs onload with browserify.
So it compiles all the modules together, wraps them in a closure as expected, but what then? I can't figure out how to tell browserify to actually run one file. ie that 1 particular file is the entry point. For instance, if I had a file like so:
// runner.js
var app = require('./app'),
$ = require('jquery');
$(function(){
app.run();
});
How do I tell browserify during build step that I want this file to actually run. For instance can I wrap it in a self invoking function?
I've read that you can expose globals with browserify, but I don't want to expose every file in my app as a global that the app can see. Ideally I don't want to expose anything, I just want the script to run.
Any help?
Scratch that, looks like browserify does indeed run the files.
I forgot I was playing with the --standalone option and that doesn't actually seem to run anything, but I think let's you just build a module that someone else can call.