joi
joi copied to clipboard
Change browser module export
Context
- node version: 12.12.0
- module version: 17.1.0
What are you trying to achieve or the steps to reproduce ?
The documentation does not make it clear how @hapi/joi/dist/joi-browser.min.js
can be imported and used like regular @hapi/joi
. I am trying to use Joi
in Karma
.
// --- What I've tried:
import Joi from '@hapi/joi/dist/joi-browser.min.js';
import * as Joi from '@hapi/joi/dist/joi-browser.min.js';
import '@hapi/joi/dist/joi-browser.min.js';
import { Joi } from '@hapi/joi/dist/joi-browser.min.js';
// ---
export const createSchema = () => {
return {
scoresStore: {
scores: Joi.array().length(4).items(Joi.number().equal(0)).required()
},
overallScoreStore: {
root: Joi.object().required(),
overallScore: Joi.number().equal(0),
overallScoreTwo: Joi.number().equal(0)
}
};
};
Could someone tell me what the issue is here?
Why are you doing deep imports? import Joi from '@hapi/joi'
should be enough.
@Marsup
import Joi from '@hapi/joi'
throws an error when ran with karma
and I'm not sure why. It works fine with standalone mocha
. This is what led me to try to import joi-browser.min.js
because I figured that the fact that I am running in a headless browser was causing the error.
the code I am running:
import Joi from '@hapi/joi';
import RootStore from '../../components/stores/root';
export const createSchema = () => {
return {
scoresStore: {
scores: Joi.array().length(4).items(Joi.number().equal(0)).required()
}
};
};
export const validate = (schema, store) => {
const { error } = Joi.object(schema).validate(store);
if (error) throw error;
};
describe('Root tests', () => {
it('test initial schema', (done) => {
const rootStore = new RootStore();
const schema = createSchema();
validate(schema, rootStore);
done();
});
});
Here is the error from karma:
START:
13 02 2020 09:43:12.128:INFO [karma-server]: Karma v4.4.1 server started at http://0.0.0.0:9876/
13 02 2020 09:43:12.129:INFO [launcher]: Launching browsers ChromeHeadlessNoSandbox with concurrency unlimited
13 02 2020 09:43:12.137:INFO [launcher]: Starting browser ChromeHeadless
13 02 2020 09:43:12.728:INFO [HeadlessChrome 79.0.3945 (Windows 10.0.0)]: Connected on socket O79s7etaUu6t9GkgAAAA with id 13936121
HeadlessChrome 79.0.3945 (Windows 10.0.0) ERROR
Uncaught SyntaxError: The requested module '../../node_modules/@hapi/joi/lib/index.js' does not provide an export named 'default'
at http://localhost:9876/context.html:0:0
SyntaxError: The requested module '../../node_modules/@hapi/joi/lib/index.js' does not provide an export named 'default'
Finished in 0.881 secs / 0 secs @ 09:43:13 GMT-0500 (Eastern Standard Time)
SUMMARY:
√ 0 tests completed
Oh you're right, we use require
for our testing. Hopefully import Joi = require('@hapi/joi')
works. This is probably something we should change in the next breaking version.
So I ended up figuring it out. I ended up doing import '@hapi/joi/dist/joi-browser.min.js'
then used joi
with a lowercase j every time that I referenced it.
import '@hapi/joi/dist/joi-browser.min.js';
// const joi = require('@hapi/joi');
import RootStore from '../../components/stores/root';
export const createSchema = () => {
return {
scoresStore: {
scores: joi.array().length(4).items(joi.number().equal(0)).required()
}
};
};
export const validate = (schema, store) => {
const { error } = joi.object(schema).validate(store);
if (error) throw error;
};
describe('Root tests', () => {
it('test initial schema', (done) => {
console.log(JSON.stringify(joi));
const rootStore = new RootStore();
const schema = createSchema();
validate(schema, rootStore);
done();
});
});
@Marsup how should this be fixed?
By exporting an ES6 compatible module. Basically either set a default
property and __esModule
to true, or export it as a Joi property dropping the default export. Or both.
You can find an example output of that in https://babeljs.io/docs/en/babel-plugin-transform-modules-commonjs.
Hey @hueniverse ,
I can help with this. Let me know if this is okay, so you can assign this issue to me.
I think this lead to others problems too.
In fact, const Tlds = require('@hapi/address/lib/tlds');
doesn't work at all in browser (return an empty object), so we have error thrown for standard documented code (a basic string().email()
).
Are there really no plans to support modern JS? Svelte and Vue (vite/rollup) don't support CommonJS.
If someone wants to open a PR that fixes it, ideally by offering a separate export so it is not a breaking change (at least initially to allow people to migrate over time), I'll review.