Webpack - Alias folder for use within installed package - javascript

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.

Related

Import Stencil JS library from another Stencil JS library

I have two libraries of Stencil JS web components, library-a and library-b. These are not apps, just separate npm packages of components.
I would like to use some of the components from library-a inside library-b. How do I import components from A into B?
The StencilJS docs offer some import instructions but don't cover this particular use case.
Basically all you have to do is npm install (or npm link) the project and import it.
As far as I know there are two places you can include the import:
Inside a global app.ts which is configured as a globalScript in stencil.config.ts.
Inside the root component.
In your case the second option probably won't work since component libraries usually don't have a root component.
Import inside app.ts:
First, create a global script and configure it in your stencil.config.ts:
export const config: Config = {
// ...
globalScript: 'src/global/app.ts',
};
Then add the import inside that file. Example for Ionic Framework:
import '#ionic/core';
Now you can use the components just like any other HTML element.

How can I build a vue library as umd module that depends on other components?

I am trying to build a vue library which should be bundled as a umd module so that it can be used via script tag in the browser. The library itself publishes a vue component and is using vuetify but does not ship with vuetify because the consumer bundles should contain it. I am using the webpack configuration externals to prevent that vuetify is part of the final bundle. I have also added vue and other dependencies there. The index.js of my library just looks like this:
import MyComponent from './MyComponent'
export default MyComponent
export {
MyComponent
}
Now I created a vue application where the library itself is loaded by a script tag in the index.html. I registered all vuetify components with Vue.component(name, component) and used Vue.component('MyComponent', MyLibrary.MyComponent) to register my custom component. Unfortunately I am getting lots of errors like Unknown custom element: <VuetifyComponent>. So the problem seems to be that the library looks for vuetify components that exist in the window scope instead of taking those components from my vue application. Is there any way to convince a umd library to take dependencies from the consuming bundle?

Javascript ES6 modules name resolution

I'm absolutely sure, that I'm asking a silly question, but I really do not understand how this line of code works
import React from 'react';
My question: who and where searches for 'react' name?
For example, this site tells me, that for module-name I should use relative of absolute path, e.g
import React from './react';
or
import React from '/home/user/react';
I thought that 'react' is same as './react' but I've created ReactJS applcation via create-react-app command and didn't find any file named react.js in application folder.
So, obviously there is some tool or rule by which module name has been resolved to a proper file, but I cannot find proper documentation about this.
Import statements are importing packages by name from the node_modules directory in your app, which is where they're saved when you run an installation command such as npm install or yarn inside your app.
When you write:
import React from 'react';
As far as you're concerned, it's as if you'd written:
import React from './node_modules/react/index.js';
Importing by package name means you don't have to be aware of how a given package is structured or where your node_modules directory is relative to your javascript file.

Error when Using Custom React Hook in a Multi-Module Project for Tests with Jest

I'm having a project with multiple Webpack modules. In my child module, I want to create a custom React hook, which I can use in React components in the parent module.
My example hook is quite simple:
export function useTitle(title: string): void {
useEffect(() => {
document.title = title
}, [title]);
}
However, when using my custom hook in a React component outside of the module, I get an error:
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app
I assume that the cause is that a React instance is created for each Webpack module. A Jest test comparing the React instance of the child module with the one of the parent module also shows this.
import {react} from "child-module";
test("react instance", () => {
expect(react).toBe(React); // serializes to the same string, but unequal
});
Is there anyway to use a custom React hook from one Webpack module in another without getting an error?
What I have already tried without any success
In my Webpack config files, I set external declarations for React to avoid that React will be included in the output Webpack bundles.
In the package.json of the child module, I have declare React as peer dependency.
In the package.json of the parent module, I have linked to the React installation of the child-module: "react": "../child-module/node_modules/react" to ensure that both modules use the same React copy.
On runtime, I make it working my delivering React from a CDN and not from any Webpack module. However, it doesn't help me much if I cannot test my React components.
I could finally solve the issue by storing React in the node_modules folder of the common root folder of the child and parent module.
My project structure:
project
|
+--- node_modules <-- React is here
|
+--+ child-module
| |
| +--- node_modules <-- Does NOT contain React
|
+--+ parent-module
|
+--- node_modules <-- Does NOT contain React

Where do external dependencies live in vanilla JS web components?

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

Categories

Resources