Global import for testing react app - javascript

If I wanted to do this in all my test.js files:
import { shallow } from 'enzyme';
import MockAdapter from 'axios-mock-adapter';
Is there a way to globally import it so that every 'tests.js' file will automatically have that imported?
Thanks in advance!!!

You can use globals!
Example:
setup.js
import { _shallow } from 'enzyme'
import _MockAdapter from 'axios-mock-adapter'
global.shallow = _shallow
global.MockAdapter = _MockAdapter
test1.js
describe('My Test 1', _ => {
MockAdapter() // Use it!
})
Notes:
Global variables will solve this particular issue. But the caveat is that you will have one instance across each test (which might be ok depending on the dependencies you import)
EDIT: In context of react-boiler-plate
If you read package.json, you'll see that there is a test setup file within "jest".
This path is react-boilerplate/internals/testing/test-bundler.js.
Edit that file with the contents of setup.js (aforementioned)
Now each one of your tests should have the variables defined

Related

Esbuild with ReactJS.NET?

TL;DR How can I use esbuild with ReactJS.NET?
Long version
ReactJS.NET expects the following from a "bundle":
React.Exceptions.ReactNotInitialisedException: 'React has not been loaded correctly: missing (React, ReactDOM, ReactDOMServer). Please expose your version of React as global variables named 'React', 'ReactDOM', and 'ReactDOMServer'
What Webpack actually does is always quite unclear to me, but looking at the ReactJS.NET Webpack tutorial here, this is the setup:
import React from 'react';
import ReactDOM from 'react-dom';
import ReactDOMServer from 'react-dom/server';
import RootComponent from './home.jsx';
global.React = React;
global.ReactDOM = ReactDOM;
global.ReactDOMServer = ReactDOMServer;
global.Components = { RootComponent };
Further at the sample webpack-config here, there is this output-setting:
{
[...]
globalObject: 'this',
}
Mirroring this in esbuild would be using iife and esbuild.globalName = 'this', but it throws an error:
> (global name):1:0: error: Expected identifier but found "this"
1 │ this
Esbuild is quite stern on that it is a bundler (not a transpile-and-concatenator), so how would I tweak Esbuild to have the bundle mutate the global object to what React.NET expects? - And is it even possible?
Thanks,
Flemming
Found a solution.
import { build } from 'esbuild'
const globalName = 'whatever'
build({
[...]
format: 'iife',
globalName,
footer: {
// Important! Assigns the raw export of the bundle to whatever `this` is in the given context
js: `Object.assign(this, ${globalName})`,
},
})

NPM package: best practices and exposing multiple import paths

I created an NPM package that uses Webpack and Babel for transpiling/bundling.
In my package.json, I've got main set to "main": "build/index.js". And in my Webpack config, I have entry set to entry: { app: './src/index.js' }. My entry file is shown below.
Everything works fine when the package is installed. However, with this setup, two import paths are exposed for every helper:
This is a problem for editors that support auto imports, since they will sometimes auto import from 'my-package/build/utils/helper1' rather than the preferred path of 'my-package'.
So, two questions:
Is there any way to prevent the longer import path from being exposed?
What is considered best practice when creating NPM packages. Is my setup acceptable, or should I be doing something different?
Entry File:
import helper1 from './utils/helper1';
import helper2 from './utils/helper2';
export {
helper1,
helper2,
};
const myPackage = {
helper1,
helper2,
};
export default myPackage;
you can utilize Webpack resolve
I often use the first way:
export {
helper1,
helper2,
};
Recently, I found that we can use Object.freeze() to export. This is a good article.
I would suggest probably merge your helper1 and helper2 in one file and name it helpers, then you can put them in the class myPackage so that you then export them as a module like this
import myPackage from './utils/helper';
// OR import {helper1, helper2} from './utils/helpers';
export default class myPackage {
helper1,
helper2,
};
OR
import {myPackage} from './utils/helpers';
// OR import {helper1, helper2} from './utils/helpers';
module.exports.myPackage = (helper1, helper2) => {
this.helper1 = helper1;
this.helper2 = helper2;
};
I hope this helps.

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'

react compile error, Module not found

I got this error in my browser
Error in ./src/App.js
Module not found: ./components/todo in C:\Users\James\Desktop\react\src
This is what I got in my editor
import {TodoForm, TodoList} from './components/todo'
http://imgur.com/a/8YLod
I even tried import {TodoForm, TodoList} from './components/todo/' I wonder what's wrong.
Imports work on a per module basis for most loaders/bundlers. In other words, you'll need to import the form and list by doing the following:
import { TodoForm } from './components/todo/TodoForm'
import { TodoList } from './components/todo/TodoList'
As a side note, see https://developer.mozilla.org/en/docs/web/javascript/reference/statements/export to make sure that you're exporting the components correctly. The curly braces around your import works for a named export as opposed to a default export.
In order to just import all files from the directory you must have an index.js file that exports everything from the directory
Which in your case the index.js file would look like this
Export * from 'TodoForm'
Export * from 'TodoList'
Note if the export statement doesn't work see this answer to fix the import / export statement
Do you think, when you wrote import {TodoForm, TodoList} from './components/todo', in TodoForm should be value than you exported from file TodoForm.js, and similarly with TodoList? It's don't works.
You should do import from some file. When you wrote from './components/todo' you tried doing import from todo directory. I guess, in egghead video that import works, because, they have index.js file in todo directory. And in this file they do export for every component separately. Try to add index.js file in todo directory with the following contents:
export * from './TodoForm.js';
export * from './TodoList.js';
it's will work.
So the thing is that when you do
import {TodoForm, TodoList} from './components/todo'
What happends is that your compiler will by default search the components TodoForm and TodoList from the index.js file since you have not mentioned explicitly which files to point to
So if in index.js you add something like
export * from './components/todo/TodoForm';
export * from './components/todo/TodoList';
Your approach will work.

Categories