SystemJS import "base script" from directory, like in Python - javascript

Is it possible to import a "base script" from a module-like directory with SystemJS, like a Python's __init__.py?
Example:
Directory structure
app/
module1/
__init__.js // or module1.js
module1.weeble.js
module1.thingy.js
module2/
__init__.js // or module2.js
module2.weeble.js
module2.thingy.js
bootstrap.js
module1/__init__.js
import Weeble from "./module1.weeble"
import Thingy from "./module1.thingy"
class Module1 {
constructor() {
this.weeble = new Weeble();
this.thingy = new Thingy();
}
}
export default Module1
bootstrap.js
Import directory to import the base script (__init__.js or module1.js) or something:
import Module1 from "./module1"
import Module2 from "./module2"
let module1 = new Module1();
let module2 = new Module2();
// INSTEAD OF
// import Module1 from "./module1/__init__"
// OR
// import Module1 from "./module1/module1"
Is this possible? Python imports a directory as a module if __init__.py is present in that directory
# so one doesn't have to type
from module/__init__.py import module_part
# but only
from module import module_part
# or to import the entire module
import module

Yup it's possible. Use a index.js file for that:
module1/index.js
Then you can import "./module1";

JavaScript itself isn't a module-based language language (not yet). In order to do this you will need to include another library like RequireJS

Related

import sub module in typescript

I am making a Shared library with the following structure
src
modules
-- module1.ts
-- module2.ts
-- index.ts // reexports from module1.ts and module2.ts
utils.ts // exports someUtils
logger.ts
index.ts // re-exports from utils.js and logger.js
Now in my service-A and service-B I can do something like
import { someUtil } from '#project/shared since someUtil is exported in the main index.ts, but how can I access something exported from module1.ts without having to do import { module1Variable } from '#project/shared/src/modules/index ?

Typescript does not load file with same name as parent folder

I have such files:
app.ts and config/config.ts
When from app.ts I try to import or require config:
import './config/config';
config file completely ignored(code inside config/config.ts is not executed) and no error occur (such as no module found), but If I rename config.ts for example to config-loader.ts and try to import config/config-loader - this works perfectly.
Can someone explain why I can't use file same name as parent folder to load this file later?
UPD:
here is content of app.ts file
import {foo} from './config/config';
console.log('from app');
console.log(foo);
./config/config.ts:
console.log('test from config');
export const foo = 'bar';
app is run with
ts-node -r tsconfig-paths/register app.ts
in console after run I see:
from app
undefined
Try to import an exported module from that file.
import {Config} from './config/config';
where Config is your exported module.
You can also use the JS way like
const config = require("./config/config")
but you will lose the typings.
In your case, the below means run a script.
import './config/config';
runs the script 'config'.

Webpack: npm module => ES6 Module to enable import

Say I have some npm module with
...
exports.abc = abc;
exports.xyz = xyz;
...
I want to generate some lib.js file which allows me to do:
import {abc, xyz} from 'path/to/lib.js';
from a javascript file I'm including in a webpage with <script type="module"></script>
I've tried
node_modules\.bin\webpack .\node_modules\package\lib.js -o .\path\to\lib.js --display-error-details --output-library my_lib
But I can't see to do any imports. I've tried
import defaultExport from "path/to/lib.js";
import my_lib from "path/to/lib.js";
import {xyz} from "path/to/lib.js";
which all give me a variant of: does not provide an export named '...'
and
import "path/to/lib.js"
console.log(my_lib);
which throws a ReferenceError

Global Import In ES6

I have a large third party library that I need to share between two projects. The project has multiple folders with multiple files that contain multiple exports. Instead of importing these modules like this
import {BaseContainer} from '#company/customproject/src/containers/BaseContainer.js'
I would like to do this
import { BaseContainer } from '#company/customproject'
I know I can manually import all the modules into a single index.js file in the base directory but i am wondering if there is an easier way to do not have import them all explicitly
I know I can manually import all the modules into a single index.js file in the base directory but i am wondering if there is an easier way to do not have import them all explicitly
You should really just create an index.js file and import into that whatever you want to export so that you can control what APIs get exported and to not export private APIs.
That said there is an automated tool that generates an index.js automatically for you:
> npm install -g create-index
> create-index ./src
Which will generate an index.js with all the exports.
As the other answer suggests, you should create an index.js within each directory and explicitly export contents
#company/customproject/index.js
import {BaseContainer, SomeOtherContainer} from './src/containers'
export {
BaseContainer,
SomeOtherContainer
}
#company/customproject/src/containers/index.js
import BaseContainer from './BaseContainer'
import SomeOtherContainer from './SomeOtherContainer'
export {
BaseContainer,
SomeOtherContainer
}
Another option to autoload an entire directory is using require and module.exports to export every scanned file, however. You would likely run into conflicts using both ES6 import/export along with module.exports and default export statements.
#company/customproject/index.js
const fs = require('fs')
const modules = {}
fs.readdirSync(__dirname+'/src/containers').forEach(file => {
file = file.replace('.js', '')
modules[file] = require('./src/containers/'+file)
// map default export statement
if (modules[file].default) {
modules[file] = modules[file].default
}
})
module.exports = modules
Then simply use it in any ES5 or ES6 module
const {BaseContainer} = require('#company/customproject')
or
import {BaseContainer} from '#company/customproject'

Properly export/import parts of a JS project

I'm building an npm package (ES6 + Babel) for the first time and I'm having trouble connecting it all together so it can be imported by the end user.
My build (output) folder structure is the same as src:
build
- index.js
- BaseClass.js
sublclasses
- SubClassA.js
- SubClassB.js
SubClassA and SubClassB import and extend BaseClass and are both exported using the module.exports. The entry point, index.js, has only two lines:
import SubClassA from './subclasses/SubClassA'
import SubClassB from './subclasses/SubClassB'
package.json has the main field set to ./build/index.js.
When installing the project (or npm linking) into a test project, I write:
import SubClassA, SubClassB from 'my-package'
Import works, but imported classes are undefined. I've tried a couple more ways to do it, but it didn't work.
How should I do it properly?
EDIT: after changing index.js to:
import SubClassA from './subclasses/SubClassA'
import SubClassB from './subclasses/SubClassB'
module.exports = SubClassA
module.exports = SubClassB
it kind of works. 'Kind of' means that if I import both classes in the test project like so:
import SubClassA, SubClassB from 'my-package'
and then do:
let sca = new SubClassA()
it turns out to be SubClassB. If I ommit SubClassB from import, it works normally.
EDIT 2 - SOLUTION:
Per instructions in the comments below, I've changed the index.js file like so:
export { default as SubClassA } from './subclasses/SubClassA'
export { default as SubClassB } from './subclasses/SubClassB'
and I imported it in the test project like so:
import { SubClassA, SubClassB } from 'my-project' and it worked.
The problem is you're not exporting anything from your main file,
using es6 import/export syntax you can directly export it with:
export {default as SubclassA} from './subclasses/SubClassA'
export {default as SubclassB} from './subclasses/SubClassB'
then to you can use the named imports :
{SubClassA, SubClassB} from 'my-package'

Categories