Load a JS dependency from browserify bundle - javascript

I have a single page app which comprises of a JS bundle based on Browserify and Coffeescript.
In a certain usecase, I need to create an adhoc page (Detached from the SPA) which needs to access a library (Kendo to be specific), which is part of the browserified bundle and the adhoc page would have some simple JS based on kendo.
The question is how do I load/access the library outside the Single Page Application (If I try loading it, the browser says that the library is not found)?
Using RequireJS could be an option as specified here. But, I dont want to use another library just for this purpose. I think there must be a way to "require" the library without requireJS because it is already working in the Single Page Application.
Please help.. Thanks!

Browserify rewrites your module paths like ../moduleA/file.js into an internal module id like 23 when packing.
Every require statement will also be rewritten, a statement like this:
var moduleA = require('../moduleA/file.js');
Becomes this:
var moduleA = require(23);
To get access to a particular library, you can do to things:
1) find the internal id via debugger and then require the module via it (this is quite fragile, because the internal id could change with every build)
2) package another file into your bundle with the following contents:
var kendo = require('kendo');
window.kendo = kendo;
Afterwards, you can simply access kendo as a page global.

Related

How to use a capacitor plugin meant to be imported in a vanilla js app

I'm currently pulling hairs trying to figure out how to go about this.
So, I'm working in a vanilla JS environment with no webpack setup served with capacitor and want to use this capacitor-plugin: https://github.com/CodetrixStudio/CapacitorGoogleAuth
However, to use this plugin I have to import the package into my client code.
Here's what I've tried:
Unpkg type="module": however browser support in mobile isn't that great. And this app will be served to a ton of users
Using browserify + esmify to bundle the plugins code into something I could import with a <script> tag into my index.html. Didn't work
My last thought is to setup webpack to bundle everything for me, similar to the browserify approach and import that. However before I go through with all of that I wanted to reach out here to see if you guys had any other ideas.
Is there a way to access this plugin from window maybe?
so I figured out the way to go about this by following this article: https://medium.com/#SmileFX/a-complete-guide-building-a-capacitorjs-application-using-pure-javascript-and-webpack-37d00f11720d
Basically you have a www/js directory (vanilla js), and a src directory (ES6/import code goes). You then configure webpack to output in your www/js/ directory.
Note: Any variable you want accessible to your vanilla js code must be explicitly stored in the window object.
Example
./src/toBeWebpacked.js
import Module from "your-module"
window.doSomething = () => Module.doSomething()
./www/js/vanilla.js
const useModuleCode = () => {
// use code from webpacked ES6 JavaScript here
return window.doSomething();
}

Can I monkeypatch a function in another webpack bundle at runtime?

I am writing a plugin for a third-party web application, whose code I can see but can't modify. I'm running it in Chrome. The main webapp and the plugin are both (separate) webpack bundles. At runtime when the page loads, the webapp fetches the plugin bundles from the same server, and initialises them.
My objective is to make my plugin patch/wrap a function in the third-party application, in the module webapp/utils/target.tsx, such that calls to that function from within the webapp have my modified behaviour. Something like this:
// somehow import the `target` module (this is the problem, see below...)
oldFunc = target.targetFunc;
target.targetFunc = function targetFunc(args) {
// do extra stuff here
return oldFunc(args);
}
But I don't know how to import the target module or whether this is possible. Specifically:
I can't just import target, because application/webapp is not a dependency of my plugin
Plugins are meant to access limited entrypoints that get attached to window by the webapp, so they have no direct dependency on the webapp
I don't think I can add application/webapp as a dependency because
it's not a published package (perhaps I can add it as a github link?) and
I don't want webpack to include it in the bundle, so I think I'd have to specify it as an external dependency, but I don't know how to do that...
I can't modify application to do any extra things in its webpack (like exposing target in a different way)
I thought perhaps I could import it dynamically at runtime:
import(/*webpackIgnore: true*/ '/application/webapp/utils/target').then({
...
})
This gives me the error Expected a JavaScript module script but the server responded with a MIME type of "text/html".
If it helps, when the page is fully loaded and the app has loaded my plugin, in Chrome developer tools under Sources -> Page, I see a tree structure like this:
- localhost:port
- .
- com.mydomain.myplugin
- <modules for my plugin>
- application
- webapp
- .
- <other modules>
- utils
- target.tsx
- <other files>
- webpack
Meanwhile the original html page source seems to load the webapp via this tag in the header:
<script defer="defer" src="/static/main.c4e2eaf1d8c47b01fa6c.js"></script>
The Chrome devtools say "Source map detected".
Is it even possible to do what I'm trying to do?
From what i understand, you can import the module object, edit with the Object. library and return the edited module. If you don't understand nothing but knows the core, these references should helpful to solve this.
https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Statements/import
https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Statements/export
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties

build react app and widget js in one webpack config

My task is to introduce library to existing create react app based application.
This library need to be build to separate chunk and should not contain any contenthash in name. Ideally should be build to buildDir/js/widget.js and that is.
Currently all my ts are compiled to js during build and are served with contenthash in name.
I don't know how to build widget.js from src/widget/index.ts because entry point is src/index.ts and it never catch src/widget/index.ts because it is not imported anywhere in main entry point.
This widget.js later will be imported in thirdparty web apps via <script> tag and it will be used to initialize some library like MyLibrary.init(...) so I think webpack should also have some info so this one widget.js should export its methods in special way to the browser during importing external script.
What is best way to get this build proces to work. Also it could be really nice to have it also during development with hot updates.
I don't want contenthash in resulting buildDir/js/widget.js because I don't want to ask my customers every time I have new version to update their <script src="..."> for new file name.
Should I eject this CRA? I'm not sure even if I add another entry point that I will be able to control output file name for one entry point as it is and for another without contenthash.
Or maybe it will be better to create separate webpack config (next to unejected CRA) for this widget but then how to run everything in development mode with hot updates?
I'm using webpack 4.42.0 here in this project.
for your case maybe you need this:
https://dev.to/zhiyueyi/include-your-react-widgets-in-any-web-page-emj
https://github.com/ZhiyueYi/demo-react-web-widget

Browserify: prevent including the same npm-module more then once in the same application

For learning purposes I am working on a small chat application, based on jQuery. I want to make it a CommonJS Module, which I can reuse in other projects, just doing something like:
var Chat = require('chat'),
mainChat = new Chat({/* ...params... */})
I am also using browserify for bundling all my dependencies. In my "chat.js" file I am doing:
var $ = require('jquery');
it gives me a local jquery object, and I don't have to worry about whether jQuery was included somewhere in the project earlier, or not. But if somewhere in my project, in another "*.js" file I will do the same thing - it will create another local jQuery object and my bundle would become really huge. My question: is there some method or tool to prevent including some npm-module more then once in the same application?
If both versions of jQuery are exactly the same, browserify will detect it in its dedupe step and include it just once.
See https://github.com/substack/browserify-handbook#dedupe for details.

Requiring external JavaScript file

After reading all the relevant answers in SO and posts in the Appcelerator forums I still can't get this to work:
I have an application developed in Appcelerator, and I want to load an external JavaScript file in some of my controllers.
My App structure is as follows:
+ app
- assets
- controllers
- models
+ lib
- IndicatorWindow.js
...
Inside a controller I have the following code:
var uie = require('lib/IndicatorWindow');
But when I run this on an Android phone I get:
Uncaught Error: Requested module not found: lib/IndicatorWindow
I have also tried placing the lib folder outside of app, and using other paths such as /lib/IndicatorWindow and app/lib/IndicatorWindow.
I even tried using Ti.include() instead, with the same result. But I would rather use require() since I prefer using CommonJS modules.
Make a lib folder inside assets folder and paste the js file there and you would be able to require file just like you do in classic :)
Thanks
just use var uie = require('IndicatorWindow');
Also make sure it uses exports inside the JS

Categories