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

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).

Related

How can you use multiple modules in a Raku project, if the modules are defined in the project?

I'm playing around with writing modules in Raku, when it made sense for me to break a piece of functionality off into another .rakumod file. How can I link these files together when I compile?
I tried to pull the other module to my main module via:
use MyProject::OtherModule;
But I get an error that it can't find this module even though they're side by side in the directory. I tried looking at some OSS projects in the Raku world, most of them are one file, the compiler Rakudo seems to use multiple module files but I can't figure out how they're linked.
Do I have to publish this module every time I want to run my project? How do I structure this if my project gets huge? Surely the best solution isn't to have it all in one file?
Edit: I should also note that I used this at the top of my new module too:
unit module MyProject::OtherModule;
When running locally, if you have your META6.json declared, you can use
raku -I. script.raku
and it will use the uninstalled versions, and you don't need to add any use lib in the script.

Include git information on parceljs build

I have a TypeScript/React web app that uses ParcelJS and I would like to have either a step in the build or a simple way of using a resource file that holds git information.
Not sure if there is something that can generate the git information during the build, I'm using npm to launch parcel.
If parcel can load a resource file and make it accessible that could also work by having properties.
My end goal would be to display version and git commit point in the webapp.
I'm going to assume you're using parcel2 (I'm not sure this would be possible in parcel1).
Parcel2 uses babel to transpile typescript by default (through the #parcel/transformer-babel plugin). The babel configuration for this plugin can be over-ridden by simply including a .babelrc (for configuration relevant to only a subset of the project) or babel.config.json file (for configuration that will apply to the entire project). See this scenario matrix that I made in the process of fixing this bug for details about exactly what babel config files should be picked up by parcel. (The "proposed fixes" are merged into parcel2 as of the latest nightly release).
With the ability to supply your own babel configuration, you should be able to use this babel plugin to inject git repository information into your code.
(Since you're using typescript, you'll also need to make sure to include #babel/preset-typescript or #babel/plugin-transform-typescript in your babel config as well).

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 handle chained dependencies in Sass projects with npm?

I have two Sass projects which I'm working on. Let's call them ProjectBase and ProjectExtended. ProjectExtended depends on ProjectBase, and the ProjectBase depends on a third party node module, namely Bootstrap.
ProjectBase should be independent but also work when used as a dependency.
ProjectBase has this include in it's Sass file:
#import '../node_modules/bootstrap/scss/bootstrap';
ProjectExtended then has this include:
#import '../node_modules/ProjectBase/scss/ProjectBase';
ProjectBase can build this without issues after running npm install because the included file is in that path under node_modules.
The problem arises in ProjectExtended because now after running npm install, the Bootstrap source is not in the same relative location anymore from the point of view of ProjectBase:
-node_modules/
|--bootstrap
|--ProjectBase
As you see in this case Bootstrap is suddenly a sibling instead of a dependency like so:
-node_modules/
|--bootstrap
|--ProjectBase
|--node_modules
|--bootstrap
As a workaround, I manually go into node_modules/ProjectBase and then run npm install in there, which installs those dependencies a second time under that folder.
Is there a better way to handle this?
This problem can be solved by providing custom importer to node-sass. I have simple implementation of such importer that you can try to use, it will allow you to configure all necessary paths and rules to resolve imports inside your .scss files.
In your case configuration may look like {roots: ['node_modules','../node_modules']} if I understand your directories structure properly.

npm: dependencies vs devDependencies with bundled dependencies

Using the search I already found some great answers to similar questions, but still I am not sure if I understood it correctly.
From these answers I learned that dependencies are required to run the application while devDependencies are only required while developing (like unit tests).
But how about this: My application depends on jQuery, but during a build step (with the help of my devDependencies), everything is bundled into one file. In this case, should I list jQuery as dependency or as devDependency?
To make my point more clear take a module like this:
define(['jquery'], function($) {
// use jQuery in this module
})
Later on, this module will be compiled into somehing like application.build.js which then contains this module and the jQuery dependency.
Since the end result is the same, there doesn't seem to be a definite rule here, but I found a couple of discussions on the matter:
If you're building an application
https://github.com/webpack/webpack/issues/520
A browser app built by [insert build tool/bundler] has no runtime node dependencies, and thus all frontend dependencies should be listed as devDependencies. The dependencies vs devDependencies naming convention stems historically from node being a server side package manager (...) It is as far as I can tell harmless to list frontend dependencies under dependencies, but it is wrong.
(...) as a general recommendation for everyone, move everything into devDependencies until it is actually needed under dependencies.
If you're building a library:
https://github.com/inuitcss/inuitcss/issues/225
In many frontend projects, all code served to the browser is compiled, there are no runtime dependencies. This would mean that there are no dependencies, only devDependencies – all dependencies are included in the build done during development.
One could also argue that dependencies are required for development as well, so it would be okay to list everything unter dependencies.
I think the fact that we have the optional distinction indicates a reasonable way to use them. It makes sense (to me) that the dependencies designation would represent the 'minimum viable' code to use and as an indicator of what's nonessential for something to work.
As I see it, anything that goes on to become part of the production code is a dependency.
Epilogue
Personally, I agree more with the last quote. It makes sense that dependencies tells us what the application code needs to run, and devDependencies what the developer needs to build/deploy/whatever the application/library.
One caveat though is that if someone npm installs your library to use the bundle as a module in their own application, they will download a lot of dependencies they don't actually need.