Where do external dependencies live in vanilla JS web components? - javascript

I'm experimenting with using web components for a project — essentially custom elements powered by attributes, ideally imported by <link rel="import">.
Here's the problem: I can't find conclusive guidance on where to stick any external libraries my component relies on, such as moment.js or even jQuery.
Most component examples I've seen strictly use vanilla JS. When they do use an external library, they often seem to drop them in using Bower or npm and and refer to them explicitly within the component's HTML:
<script type="text/javascript"
src="/bower_components/jquery/dist/jquery.min.js></script>
These days I'm more accustomed to using webpack to bundle dependencies, so this seems a bit odd.
My question: is it considered better form to include each component's library dependencies within the component directory, or have a central node_modules folder at the project level? How does webpack fit into this?

It's better to have a central node_modules folder at the project level. Most people use Webpack to bundle their code with their dependencies. They use require or import their modules for each component.
a.component.js
import React from 'react'
import $ from 'jquery'
b.component.js
import React from 'react'
app.js
import A from 'a.component.js'
import B from 'b.component.js'
Webpack will have one "entry": app.js and compile it output: app.min.js
why?
It's easier to manage (update, delete, add) dependencies with npm.
The browser will load one file instead of multiple external files.
External info:
https://webpack.js.org/concepts/
https://www.quora.com/Why-use-Bower-when-there-is-npm

Related

Webpack - Alias folder for use within installed package

I have some reusable React components published to NPM, that I am installing and using within my React application. Is it possible for me to set an alias in my React app, that can be used within these NPM components? For example, I want to allow the use of a folder common, which is within my React App, within the React components. So if I do this in my React components, it should work
import someVal from 'common';
I am bundling these React components with Webpack, and sending down the transpiled, bundled version for use within the React application. I tried setting the alias the regular way within the React app webpack config (by setting resolve.alias), but it does not work. Can this be done? Or am I approaching this incorrectly? Any suggestions would be great, thanks!
Edit: So the React components from NPM are within my node_modules folder, and it is already bundled up via it's own Webpack config. I then run these components through my React application Webpack config as well (I'm whitelisting the folder), in the hopes that the new common alias will be added there. But no luck. I keep getting a
someVal is undefined error.
My common file has the following: Ignore the logic for now (I'm only posting a part of the code)
import _myClass from '../components/MyClass';
const myClass = _myClass; // Other things are done to it
export default myClass;
In my React components Webpack bundle file (after I fixed the default import statement)
/* harmony import */ var common__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! common */ "./src/common/index.js");
...
return common__WEBPACK_IMPORTED_MODULE_25__["default"].myFunction({
...
});
This still seems to be looking for common within the React components package, and not within the React app package that I am trying to use this in.

How to export multiple library variants from a single NPM package

I'm creating a node library that could be partially used in web browsers.
My current structure is something like:
package.json
lib/
index.js
node.js
web.js
modules/
some-function.js
some-node-function.js
some-web-function.js
...
"lib/index.js" is specified as "main" in package.json
I'm using each file inside lib/ to re-export functions from modules/ filtered by target (all/node/web)
And I would like to use it like this:
import fullLibrary from "my-library";
import {someFunction} from "my-library";
import webOnlyLibrary from "my-library/web";
import {someWebFunction} from "my-library/web";
import nodeOnlyLibrary from "my-library/node";
import {someNodeFunction} from "my-library/node";
BUT keeping index.js, node.js and web.js inside /lib!
Currently only the first two import statements work (because index.js is pointed from package.json).
I know that I could place those files in the root of the package and it would work as expected when importing, but I was wondering if there was a way to do the same while keeping the files in /lib for cleanness.
In any case, is this the recommended way to expose multiple variants of a same library from a single NPM package?
Just for anyone that is having similar questions regarding libraries structure and organization.
Back then I started working with monorepos using Lerna and Yarn Workspaces and I haven't regret it. I think this is the most efficient way to go in terms of modularity, readability, scalability and maintainability.
Specifically, the question code would be traduced into this:
import webOnlyLibrary from "#my-library/web";
import {someWebFunction} from "#my-library/web";
import nodeOnlyLibrary from "#my-library/node";
import {someNodeFunction} from "#my-library/node";

How to create and publish a vue global function to NPM?

I know it sounds a bit confusing, but let me explain it here:
Right now there's a module that can be imported as CDN only:
<script src='https://www.example.com/example.min.js'></script>
after including it in index.html (or any .html file)
There's a few functions that can use from the module
<script>
$example_function.doSomething(param1,param2);
$example_function.doSomething2();
</script>
Because the module does not available as NPM package and for people like me want to use it in webpack built Vue.js project it's not so straight forward to use this module.
I know there's plenty of ways to workaround but I want it to be simple as I can just import it globally like other npm packages
import Example from 'example'
Vue.use(Example)
then I can call the function in any Vue components, or in my future vue projects.
Is it possible to achieve this?

Importing Libraries Into React with SystemJS

Am a new bee with React and I usually have custom css files and libraries I use for my web app development. I have been able to import my css files with require and css-loader npm install. I want to know If I can use SystemJS to import libraries like waves.js from bower_components and use it like I would in JQuery/Javascript Waves.attach(".btn:not(.btn-icon):not(.btn-float)"), Waves.attach(".btn-icon, .btn-float", ["waves-circle", "waves-float"]), Waves.init()
If it is possible how would I do this and If not how can I import waves because into my project.
I imported my waves.js file like so without system js and called the attach functions in the componentDidMount function and it worked like a charm
import Waves from "../../libs/bower_components/Waves/dist/waves.min.js";
componentDidMount() {
Waves.attach(".btn:not(.btn-icon):not(.btn-float)");
Waves.attach(".btn-icon, .btn-float", ["waves-circle", "waves-float"]);
Waves.init();
}

React: Good Practices For CDNs, Node_Modules and Both

Been building a React application on top of create-react-app which uses Webpack through react-scripts and has React/Redux/React-dom, etc. as dependencies in our package.json.
To use those JS dependencies, we use import statements, however, for other JS dependencies (i.e. the JS used in Bootstrap and jQuery), we import those through CDN. (We have the Bootstrap CSS files in our CSS directory, and use import statements).
Is there a generally accepted practice to use CDNs vs node_modules or both on the front-end side?
My initial thought was to use CDNs to get static JS files if you're not going to use them as imports in your JS files, but wondered if that was the right way to think about it.
Obviously this isn't a React specific question, just using React to give more context.
Here's what I generally do:
(1) Setup webpack.config.js to assume global React and ReactDOM variables are available, to prevent them from being transpiled, minified, and bundled on every build. You can still use import statements in your files, as before, but the libraries will not be in your final bundle:
externals: {
'react': 'React',
'react-dom': 'ReactDOM'
}
(2) Use a CDN like http://www.jsdelivr.com/, which allows you to get multiple scripts as a single concatenated string, in a single request. This will minimize loading time.
(3) (Optional) Install React and ReactDOM as deps, and have the build process copy the minified js files from node_modules/react(-dom)/dist to your project's public files directory, and then create simple checks for the variables at the foot of the page, to inject includes pointing to your server, if the CDN calls happen to fail. For example:
if (!window.React) {
$('head').append('<script src="/js/react.min.js">')
}

Categories

Resources