Propper way to make a javascript library (with multiple files) - javascript

I want to make my own javascript library with some utils functions and classes for the client browser. The point its I only want to include the main file.
https://github.com/encarbassot/elioUtils.js
I've tried using the type module
having ./src/array.js, ./src/math.js, ./src/dom.js with some functions with export, thei i have two options
OPTION 1:
/lib/utils.js
import * as array from "./src/array.js"
import * as dom from "./src/dom.js"
import * as math from "./src/math.js"
export {array,dom,math}
but in the script i have to do:
script.js called from html
import {math} from "/lib/utils.js"
const {lerp} = math
the point of modules is to import only the functions you need and here i'am importing all math functions
OPTION 2:
import {zip,create2DArray} from "./src/array.js"
import {isTouchDevice,coptyToClipboard,scrollToCenter} from "./src/dom.js"
import {lerp,inverseLerp,map,clamp} from "./src/math.js"
export {zip,create2DArray,isTouchDevice,CopyToClipboard,lerp,inverseLerp,map,clamp}
but in this example every function i create in some ./src/ file i have to modify the utils.js file
also all libraries i use they dont use module, they are a big class or a big function
i thought about putting all inside a big object like
const utils = {}
utils.lerp = (start,end,amt)=>{
return (1-amt)*start+amt*end
}
// ... and more functions
or using multiple files and then compile them to the big file maybe ???
other option would be to do
document.write('<script src="/lib/src/math.js"></script>');
document.write('<script src="/lib/src/dom.js"></script>');
document.write('<script src="/lib/src/math.js"></script>');
but for what i think its not a very good practice
and last, jQuery you can import the file like a module and like a src file
and i'm trying to avoid things like webpack, i want to keep it vanila

Related

Exporting one set of functions from multiple files

I've just finished writing a big quickbooks wrapper in JavaScript with a lot of parts in different files, e.g. a file for tax, a file for accounts, a file for auth, etc. I'd like to make it so that developers using this wrapper will only have to do one import that will contain all the functions I've written.
Hierarchy is something like this:
QbTax.js
QbAccounts.js
QbAuth.js
I'd like to have another file, or a way that a developer using this wrapper would only have to import one thing, then be able to call all functions from the above files from that one import.
Something like this:
import * as qb from './unifiedQbFile.js';
qb.thisIsATaxFunc();
qb.thisIsAnAccountsFunc();
qb.thisIsAnAuthFunc();
What is the best way to approach this?
The only idea I have at the moment is to write prototypes in a file (unifiedQbFile.js for instance) and export those. I'd import all the functions from my other files in that unified file then call them in my new prototypes. That seems messy though.
you can have one index.js file that exports all files then you can import that index.js file. I would personally go with this method.
// index.js
export { qbTaxFunc } from 'QBTax';
export { qbAccountsFunc } from 'QbAccounts';
export { qbAuthFunc } from 'QbAuth';
Now in some other script to import it you can do.
import qb from 'path-to-index.js';
// All functions should now be available
qb.qbTaxFunc();
qb.qbAccountsFunc();
qb.qbAuthFunc();

How to import a file that already imports another file?

Javascript, ES6. I have three files:
inline-functions.js
\*
Bunch of small functions.
*/
some-module.js
import './inline-functions.js'
// uses many inline functions
main.js
import './inline-functions.js'
import './some-module.js'
// uses inline functions as well as classes from some-module.js
Now, I use Visual Studio Code and I would like Intellisense working but when I am editing main.js, it only shows functions from inline-functions.js and everything from 'some-module.js' is unreachable even though there is an import statement. However, when I comment the import out of some-module.js like this:
// import './inline-functions.js'
// tries to use inline functions which are now not callable
Intellisense suddenly shows correct names and documentation for all objects. This is of course unusable because some-module.js now can't call any of the inline functions.
What is the correct way of importing these modules?
You can access the module function only if you export it from the module.
Export the function form the module then you will see it in main js.
Example:
some-module.js
import './inline-functions.js'
const someFuncion1 = () => 1;
const someFuncion2 = () => 2;
export {
someFuncion1,
someFuncion2
}
main.js
import * as inline './inline-functions.js'
import * as some './some-module.js'
//Access it like
inline.<function name>
some.<function name>

Webpack global variable from multiple files

I'm trying to rewrite bunch of legacy JS files into module structure. I have obfuscated plugin which contains out of few files, which in turn work with single global variable. The order of execution of these files matters.
Example:
file1.js
var myModule = {someStuff};
file2.js
myModule.someProperty = someValue;
What i want to achieve is to import them all somehow and get this global variable myModule.
Possible implementation:
myModule.js
import myModule from "file1.js";
import myModule from "file2.js"; // ofc i know it does not work this way
export default class myProgramm {
constructor(){
myModule.run({options});
}
}
What i tried so far is webpack provide plugin (https://webpack.js.org/plugins/provide-plugin/), but it doesn't work with multiple files. Also i tried to use provide-multiple-plugin (adopted to webpack 4) from this gist :https://gist.github.com/shellscape/a7461022503f019598be93a512a1901a. But it seems to include files in nearly random order, so it can happen that myModule is not defined, while file2.js is executed first.

Dynamically reference static ESNext imports

Say I have these imports:
import clearLineReporter from '../modules/clear-line-reporter';
import karmaReporter from '../modules/karma-reporter';
import metaTestReporter from '../modules/meta-test-reporter';
import stdReporter from '../modules/std-reporter';
import tapJSONReporter from '../modules/tap-json-reporter';
import tapReporter from '../modules/tap-reporter';
import webSocketReporter from '../modules/websocket-reporter';
these must be referenced like I do above, in other words, I obviously can't do this:
const imports = {
stdReporter: import(...),
tapJSONReporter: import(...),
...
webSocketReporter: import(...)
}
Is there any way I can reference imported files through some form of reflection? Because it seems like I can't group them together to reference them somehow.
Instead of import syntax, I could use require(), but I am wondering if there is some way I can do some dynamic things with import statements, for example reference them all dynamically, such that if I add or remove an import, I don't have to change any other code.
There is a great answer to this question that I discovered by asking a different question, here:
exporting imports as a namespace with TypeScript
Create a file name grouped-modules.ts for example, where you want to simply list only the modules and export each one.
export {default as clearLineReporter} from '../modules/clear-line-reporter';
export {default as karmaReporter} from '../modules/karma-reporter';
export {default as metaTestReporter} from '../modules/meta-test-reporter';
...
export {default as stdReporter} from '../modules/std-reporter';
export {default as tapJSONReporter} from '../modules/tap-json-reporter';
Then in your module you can just do :
import * as mods from './grouped-modules'
export {mods}
It will export both types and values in a namespace called s. You can then import them using :
import {mods} from 'your-module'
const anObject: mods.clearLineReporter = ...;
This allows you to dynamically group your modules into one variable.
Is there any way I can reference imported files through some form of reflection?
Answer is dependent on environment, meant in questing, because import statement can be ES native modules implementation in browser, or babel-ed to require statements in node.js, or compile-time resolved bindings in webpack.
So, in each case there is solution to do something reflection. In node.js with babel-ed code import is just require wrapper, so any information is available there.
In browser with native ES modules, all requests to them can be served via ServiceWorker, so it can provide necessary information about fetched ES modules. Also in browser ES modules can be dynamically imported that way: https://matthewphillips.info/posts/loading-app-with-script-module
Most interesting part is webpack: compile-time resolve and semi-reflection can be achieved by externals resolver in functional style (https://webpack.js.org/configuration/externals/#function), and runtime by load module API (https://webpack.js.org/api/module-variables/#webpack_modules-webpack-specific- )

Javascript JSX, illegal import declaration

I have a jsx file using React components with Reflux. There is only one tiny action:
var ClickedAction = Reflux.createActions([
'clicked'
]);
How can I move this action to another file? According to the JSX documentation, it should be easy to include other files:
// import all classes that do not start with "_" from "a.jsx"
import "a.jsx";
I tried to move it in actions/clickedAction.jsx (or .js) and import it using import "actions/clickedActions.jsx" but I keep getting Illegal import declaration. How can I achieve this?
I am not using RequireJS and would like to avoid it if possible. One alternative solution I have found is to include this in the HTML file,
<script type='text/javascript' src='xxxxx/actions/clickedAction.js")'></script>
, but this is not ideal and would like to find another way. Thanks for your attention and help.
If you use Babel:
export default ClickedAction; // in action file
Otherwise, use old modules:
module.exports = ClickedAction; // in action file
require('actions/clickedActions.jsx'); // in another file

Categories

Resources