Table of Contents
Reactjs Development
The project is setup to use postcss-modules.
1. Global CSS with 3rd party components
The combination of react, postcss-(modules) cause some CSS rendering problem with 3rd party components such as reactstrap.
Reacstrap does not include bootstrap CSS but assumes bootstrap CSS is imported by the html. Postcss-modules anonymize imported bootstrap classes, hence changing the original class names. As the result, reactstrap component, e.g., modal, can not be styled.
A solution is described here https://github.com/reactstrap/reactstrap/issues/849
1.0.0.1 Example Modal.js
dang@localhost:.../django_maxo36/react_maxo36> cat src/components/Modal.js
import React, { Component } from "react";
import bootstrap from 'bootstrap/dist/css/bootstrap.css';
import {
Button,
Modal,
ModalHeader,
ModalBody,
ModalFooter,
Form,
FormGroup,
Input,
Label,
Util // https://github.com/reactstrap/reactstrap/issues/849
} from "reactstrap";
export default class CustomModal extends Component {
constructor(props) {
super(props);
this.state = {
activeItem: this.props.activeItem
};
}
handleChange = e => {
let { name, value } = e.target;
if (e.target.type === "checkbox") {
value = e.target.checked;
}
const activeItem = { ...this.state.activeItem, [name]: value };
this.setState({ activeItem });
};
render() {
const { toggle, onSave } = this.props;
Util.setGlobalCssModule(bootstrap);
return (
<Modal isOpen={true} toggle={toggle}>
<ModalHeader toggle={toggle}> Todo Item </ModalHeader>
<ModalBody>
<Form>
<FormGroup>
<Label for="title">Title</Label>
<Input
type="text"
name="title"
value={this.state.activeItem.title}
onChange={this.handleChange}
placeholder="Enter Todo Title"
/>
</FormGroup>
<FormGroup>
<Label for="description">Description</Label>
<Input
type="text"
name="description"
value={this.state.activeItem.description}
onChange={this.handleChange}
placeholder="Enter Todo description"
/>
</FormGroup>
<FormGroup check>
<Label for="completed">
<Input
type="checkbox"
name="completed"
checked={this.state.activeItem.completed}
onChange={this.handleChange}
/>
Completed
</Label>
</FormGroup>
</Form>
</ModalBody>
<ModalFooter>
<Button color="success" onClick={() => onSave(this.state.activeItem)}>
Save
</Button>
</ModalFooter>
</Modal>
);
}
}
1.0.0.2 Example App.js
dang@localhost:.../django_maxo36/react_maxo36> cat src/components/Modal.js
import React, { Component } from "react";
import bootstrap from 'bootstrap/dist/css/bootstrap.css';
import {
Button,
Modal,
ModalHeader,
ModalBody,
ModalFooter,
Form,
FormGroup,
Input,
Label,
Util // https://github.com/reactstrap/reactstrap/issues/849
} from "reactstrap";
export default class CustomModal extends Component {
constructor(props) {
super(props);
this.state = {
activeItem: this.props.activeItem
};
}
handleChange = e => {
let { name, value } = e.target;
if (e.target.type === "checkbox") {
value = e.target.checked;
}
const activeItem = { ...this.state.activeItem, [name]: value };
this.setState({ activeItem });
};
render() {
const { toggle, onSave } = this.props;
Util.setGlobalCssModule(bootstrap);
return (
<Modal isOpen={true} toggle={toggle}>
<ModalHeader toggle={toggle}> Todo Item </ModalHeader>
<ModalBody>
<Form>
<FormGroup>
<Label for="title">Title</Label>
<Input
type="text"
name="title"
value={this.state.activeItem.title}
onChange={this.handleChange}
placeholder="Enter Todo Title"
/>
</FormGroup>
<FormGroup>
<Label for="description">Description</Label>
<Input
type="text"
name="description"
value={this.state.activeItem.description}
onChange={this.handleChange}
placeholder="Enter Todo description"
/>
</FormGroup>
<FormGroup check>
<Label for="completed">
<Input
type="checkbox"
name="completed"
checked={this.state.activeItem.completed}
onChange={this.handleChange}
/>
Completed
</Label>
</FormGroup>
</Form>
</ModalBody>
<ModalFooter>
<Button color="success" onClick={() => onSave(this.state.activeItem)}>
Save
</Button>
</ModalFooter>
</Modal>
);
}
}
2. TS ES default export
2.1 Problem
{ Error: 'default' is not exported by node_modules/warning/warning.js, imported by node_modules/react-popper/lib/esm/Reference.js
Rollup can not convert exports = <something> to a default export or a namespace export in ESM and fails .
2.2 Good explaination
First and foremost, the “conf” package uses exports = <something>, which has no direct equivalent with ES Modules. Is it a default export? Is it a namespace export? It is ambiguous. Because of that, if you were to attempt building this with tsc you would get an error because import Conf from “conf” is ambiguous to TypeScript too since the module doesn't include any explicit default exports.
So you'll need to add the allowSyntheticDefaultImports: true option to your tsconfig.json file to make TypeScript treat exports = <something> as a default export. This only affects static analysis and doesn't affect emit.
Now, moving on from that, I see you are targeting CommonJS but are attempting to bundle your external dependencies. Unless you have a good reason to do it, with Rollup, you generally pass the module specifiers to your external dependencies to Rollup with the external option:
export default {
// ... external: [ "conf" ]
} That way, a require() call will be present in your bundled output that imports the conf module. Because of that, you won't need to use @rollup/plugin-commonjs which is only relevant when you want to inline your external dependencies inside your bundle and some of them are based on CommonJS modules. @rollup-plugin-commonjs has no way of transforming exports = <something> into equivalent ES Modules, so it doesn't. That's why Rollup doesn't see any default exports inside the file - @rollup/plugin-commonjs had to bail out. Beyond that, one of the transient dependencies of the conf library, ajv, imports some JSON content, so you would also need @rollup/plugin-json. And, another transient dependency, uri-js, is based on UMD and not CommonJS, so you would need to figure out a way to convert that into ES Modules as well.
The general convention with Rollup is to mark all of your dependencies from your package.json as external in your config, unless you are bundling a web application that need to run client-side in which case you'll definitely need to bundle in your external dependencies.
As I hope is clear by now, Rollup understands ESM and only ESM, and everything else - CommonJS, JSON, UMD, AMD, etc, needs separate plugins to work,but it is not always possible or feasible to rewrite that into ESM.
If you still want to inline the conf module, I've built a Custom Transformer that can rewrite CommonJS and UMD into valid ESM, it covers more use cases than @rollup/plugin-commonjs that I can help you with setting up if you want.
3. rollup plugins positions
... resolve commonJS nodePolyfill ...