I have the following structure of my app:
index.js
const app = require("./app")
exports.api = app(...)
app.js
//all the imports goes here
//and exporting the main function
module.exports = app => {...}
Now I need to bundle app.js with webpack but index.js must stay intact
The question is, after bundling the app.js, how can I require it's main function app from index.js?
After webpacking app.js I'm getting error in index.js that says "app is not a function" which makes sense since app.js content is now wrapped in webpack staff.
Any suggestions are much appreciated.
Your "app" bundle needs to be exported as a commonjs.
module.exports = {
//...
output: {
library: 'app',
libraryTarget: 'commonjs',
}
};
The return value of your entry point will be assigned to the exports object using the output.library value. As the name implies, this is used in CommonJS environments.
So, in your index.js you can require('./dist/bundle-name.js').
seems to be a hack, but I made it work by adding an intermediate file and adjusting app.js and index.js like below:
index.js
const app = require("./bundle").app //changed to named import
exports.api = app(...)
bundle.js //an intermediate file which is now an entry point for webpack
import app from "./app"
exports.app = app
app.js
//all the imports goes here
//and exporting the main function
export default app => {...} //changed to default export
If anyone has explanation on why it works this way and how to simplify it without adding that bundle.js file, you are very welcome to comment!
Related
I have a file that I want available app wide, if the file is called app_wide.js normally I would do
import util from './app_wide.js'
However, I it is a small file and I want its exports available in all my files without the explicit import command. How can I go about doing this?
I'm using Webpack to build a React application.
Maybe you can use webpack provide-plugin
https://webpack.js.org/plugins/provide-plugin/
for example:
hello.js
const hello = () => {
console.log('hello');
};
module.exports = hello;
webpack.config.js
plugins: [
new webpack.ProvidePlugin({
$hello: path.resolve(path.join(__dirname, './hello.js'))
// ...
})
]
App.js
// don't need imported or required hello from 'hello.js'
$hello()
when you use typescript don't forget to declare the type
hello.d.ts
declare function $hello(): void;
i'm having an circular dependency warnings in my node project that caused by index.js file that i wrote to combine some exports, the file look like this: path: utils/index.js.
const mysql = require('./mysqlDB');
const logger = require('./logger');
const ServerError = require('./ServerError');
module.exports = {
mysql,
logger,
ServerError
}
so I can import those in other files like this (lets said its called user.js):
const { logger, mysql, ServerError } = require('../utils');
so now if im requring user.js in another file thats include also things from utils.js
im getting the circular dependency warnings and errors after that...
when i deleted the index.js file that I wrote and requried the utils directly int my user.js file the warnings gone.
I'm not sure what I do wrong.
Thanks.
I have the following structure in my app
content/
helpers/
parsers/
parseComment.js
index.js
index.js
interactions.js
index.js
In parseComment.js module I am doing:
import { isLiked } from "../../interactions";
And, at the same time, in interactions.js module I am doing:
import parseComment from "./helpers/parsers/parseComment";
Which results in the following cycle:
interactions.js -> helpers/parsers/parseComment.js -> interactions.js
I have tried modifying the interactions module import, like this:
import { parseComment } from "./helpers/parsers";
or this
import { parseComment } from "./helpers";
in order to use a third module (index.js)... but, the cycle still exists.
How can I break it?
Note:
in content/index.js I am exporting interactions.js
in content/helpers/index.js I am exporting the parsers files and other stuff contained in the helpers folder
in content/helpers/parsers I am exporting all the parsers
Move isLiked to a new file:
content/
helpers/
parsers/
parseComment.js
index.js
likes.js
index.js
interactions.js
index.js
Make sure that new file is NOT dependent on interactions.js. That should break your cyclic dependency.
If isLiked DOES depend on other things in interactions.js, then I'm afraid you have some surgery ahead of you.
I have a completed Vue app that I am trying to 'build' and then trying to use in another app as an import.
In main.js
export function appInit(options = {}){
new Vue({
render: h => h(App),
store,
router
}).$mount('#app')
}
I also tried
export default function appInit(....)
I then build the project using a vue.config.js file using this command.
vue-cli-service build --target lib --name myApp
This generates a /dist folder with
myApp.common.js
myApp.common.js.map
myApp.umd.js
myApp.umd.js.map
myApp.umd.min.js
myApp.umd.min.js.map
I have tried the common.js file and the umd.min.js file in another app and imported them like this.
import MyApp from './js/myApp.common.js'
//or
import MyApp from './js/myApp.umd.min.js'
//or
import MyApp from './js/myApp.common'
//or
import MyApp from './js/myApp.umd.min'
Then underneath I call.
MyApp.appInit()
I even tried
MyApp()
In every case, this is the error..
"export 'appInit' was not found in './js/myApp.common.js'
or in any other of the files I tried.
Furthermore, I searched myApp.common.js and myApp.umd.min.js looking for the string 'appInit'. After all, that IS the function name I need to call. It does not exist in either file. Of course.
Is that the problem, that named exports do not work on obfuscated files? What am I missing here?
I have even tried this..
I created var with just the Vue object
var MyApp = new Vue({
render: h => h(App),
store,
router
})
Then an export function that returns it
export function appInit(){
return MyApp
}
In my test app I am importing the common.js build file with:
import appInit from './js/myApp.common'
Then I did
appInit.$mount('#app')
appInit should be the function I exported.
export 'default' (imported as 'appInit') was not found in './js/myApp.comm
on'
I'm trying to figure out an issue I have with ES6 modules import.
This is a very simplified version of what I'm attempting to do. My current file structure is much more complicated with nested folders.
I have 2 ReactJS components:
/buttons
/MyComponent1.js
/index.js
/texts
/MyComponent2.js
/index.js
/index.js
My files look something like this:
I'm importing the MyComponent2 from the root index.js file which is the entry-point of my package.
MyComponent1.js
import MyComponent2 from '../../';
export default () => (
<div><MyComponent2 /></div>
);
MyComponent2.js
export default () => (
<div>Hello world</div>
);
My buttons/index.js and texts/index.js files export all components in their own folder:
buttons/index.js
export { default as MyComponent1 } from './MyComponent1';
texts/index.js
export { default as MyComponent2 } from './MyComponent2';
And my root index.js export all my folders to make them publicly available. It's my entry-point:
export * from './buttons';
export * from './texts';
So when I import MyComponent2 in MyComponent1 from the root index.js file, it's undefined. When I import it from ./MyComponent2.js, it's defined. When I import the entire package in another project and import MyComponent2 from the root index.js file, it's defined.
It's mind-blowing and I don't understand why I can't import MyComponent2 from the root index.js file.
I need to do that because I have a set of hundred of components nested in different folder and I want to make them all available from this entry-point file.
Can someone tell me what is happening and how to make this possible?
Thanks
Okay, took me a while to figure out what is happening. Please take a look at the sandbox i've setup - https://codesandbox.io/s/nk0qmo096j
I've tried to keep the folder/module structure similar to what you've described. Please look through how the folder/modules are structured before you continue reading.
When you run the code in the sandbox, take a look at the console. You'll see something like this -
So let me try to explain why what you're trying to do is not working
buttons/MyComponent is the first file to be "exported" (since its at the bottom of the dependency chain; Project/index -> components/index -> buttons/index -> buttons/MyComponent)
Note that components/index has not been exported yet, so it will return undefined
Then buttons/index is exported, followed by texts/index
Then buttons/MyComponent is rendered; just before it is rendered i manually require components/index and it is now defined so returns some defined value
In essence, when your MyComponent1 is trying to import MyComponent2 via the index file, the index file has not been exported yet so it returns undefined. To work around this, you have to require MyComponent2 from within MyComponent1's render method.
you can import all the components from the respective component files and then assign them to a variable in the root component and then export all of them as objects.
import MyComponent1 from './buttons/index'
import MyComponent2 from './texts/index'
export {MyComponent1, MyComponent2}
to import this components in another file or project. you could import only one them using object destructuring.
import {MyComponent1} from 'index.js'
import {MyComponent2} from 'index.js'
In my case, I had an old js file that the IDE imported instead of the updated ts file. so if your module file is module.js make sure there isn't a compiled old module.js in the same directory