New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
Named exports in umd builds #2141
Conversation
- Hoist dev dependencies for build tools to root - align all external versions to be the same - add or remove missing peers - add build:dev script for development testing
- bring rules to top config - allow for multiple output targets [umd, cjs, ...] - add externals for umd builds for consistant namespacing - umd externals map names to their correct target
- Change src to coreSrc for clarity - removes complexity of linking webconfig from netlify-cms to core to base
- The library needed to have named exports using umd in scripts
- uses main webpack config - imports from new globals - change core to export default registry and init
Preview proposed changes to the CMS demo site in the link below: Built with commit c9a9aea |
default on umd exports would not be needed in script imports
The named exports are not exposed in the module libraries, only exported to the target `window` from within the module bundle. We want to make sure we follow that pattern, even if we are using `/src` in the `netlify-cms-js` bundle.
Follow Up (React as Peer):The following code produces a bundle using the proposed umd bundled libraries with react and react-dom as a peer dependency (external). import * as CMS from 'netlify-cms-core';
/** Backends */
import { Control as NetlifyCmsBackendGithub } from 'netlify-cms-backend-github';
import { Control as NetlifyCmsBackendGitlab } from 'netlify-cms-backend-gitlab';
import { Control as NetlifyCmsBackendGitGateway } from 'netlify-cms-backend-git-gateway';
import { Control as NetlifyCmsBackendBitbucket } from 'netlify-cms-backend-bitbucket';
import { Control as NetlifyCmsBackendTest } from 'netlify-cms-backend-test';
/** Widgets */
import * as NetlifyCmsWidgetString from 'netlify-cms-widget-string';
import * as NetlifyCmsWidgetNumber from 'netlify-cms-widget-number';
import * as NetlifyCmsWidgetText from 'netlify-cms-widget-text';
import * as NetlifyCmsWidgetImage from 'netlify-cms-widget-image';
import * as NetlifyCmsWidgetFile from 'netlify-cms-widget-file';
import * as NetlifyCmsWidgetDate from 'netlify-cms-widget-date';
import * as NetlifyCmsWidgetDatetime from 'netlify-cms-widget-datetime';
import * as NetlifyCmsWidgetSelect from 'netlify-cms-widget-select';
import * as NetlifyCmsWidgetMarkdown from 'netlify-cms-widget-markdown';
import * as NetlifyCmsWidgetList from 'netlify-cms-widget-list';
import * as NetlifyCmsWidgetObject from 'netlify-cms-widget-object';
import * as NetlifyCmsWidgetRelation from 'netlify-cms-widget-relation';
import * as NetlifyCmsWidgetBoolean from 'netlify-cms-widget-boolean';
import * as NetlifyCmsWidgetMap from 'netlify-cms-widget-map';
/** MediaLibraries */
import uploadcare from 'netlify-cms-media-library-uploadcare';
import cloudinary from 'netlify-cms-media-library-cloudinary';
/** EditorComponents */
import image from 'netlify-cms-editor-component-image';
/** Backends */
CMS.registerBackend('git-gateway', NetlifyCmsBackendGitGateway);
CMS.registerBackend('github', NetlifyCmsBackendGithub);
CMS.registerBackend('gitlab', NetlifyCmsBackendGitlab);
CMS.registerBackend('bitbucket', NetlifyCmsBackendBitbucket);
CMS.registerBackend('test-repo', NetlifyCmsBackendTest);
/** Widgets */
CMS.registerWidget('string', NetlifyCmsWidgetString.controlComponent) NetlifyCmsWidgetString.previewComponent);
CMS.registerWidget('number', NetlifyCmsWidgetNumber.controlComponent) NetlifyCmsWidgetNumber.previewComponent);
CMS.registerWidget('text', NetlifyCmsWidgetText.controlComponent) NetlifyCmsWidgetText.previewComponent);
CMS.registerWidget('list', NetlifyCmsWidgetList.controlComponent) NetlifyCmsWidgetList.previewComponent);
CMS.registerWidget('markdown', NetlifyCmsWidgetMarkdown.controlComponent) NetlifyCmsWidgetMarkdown.previewComponent);
CMS.registerWidget('image', NetlifyCmsWidgetImage.controlComponent) NetlifyCmsWidgetImage.previewComponent);
CMS.registerWidget('file', NetlifyCmsWidgetFile.controlComponent) NetlifyCmsWidgetFile.previewComponent);
CMS.registerWidget('date', NetlifyCmsWidgetDate.controlComponent) NetlifyCmsWidgetDate.previewComponent);
CMS.registerWidget('datetime', NetlifyCmsWidgetDatetime.controlComponent) NetlifyCmsWidgetDatetime.previewComponent);
CMS.registerWidget('select', NetlifyCmsWidgetSelect.controlComponent) NetlifyCmsWidgetSelect.previewComponent);
CMS.registerWidget('object', NetlifyCmsWidgetObject.controlComponent) NetlifyCmsWidgetObject.previewComponent);
CMS.registerWidget('relation', NetlifyCmsWidgetRelation.controlComponent) NetlifyCmsWidgetRelation.previewComponent);
CMS.registerWidget('boolean', NetlifyCmsWidgetBoolean.controlComponent);
CMS.registerWidget('map', NetlifyCmsWidgetMap.controlComponent) NetlifyCmsWidgetMap.previewComponent);
/** MediaLibraries */
CMS.registerMediaLibrary(uploadcare);
CMS.registerMediaLibrary(cloudinary);
/** EditorComponents */
CMS.registerEditorComponent(image);
export const NetlifyCmsReact = CMS;
export { CMS as default };
{
"dependencies": {
"create-react-class": "^15.6.3",
"emotion": "^9.2.6",
"immutable": "^3.7.6",
"lodash": "^4.17.10",
"moment": "^2.24.0",
"netlify-cms-backend-bitbucket": "^2.0.0",
"netlify-cms-backend-git-gateway": "^2.0.0",
"netlify-cms-backend-github": "^2.0.0",
"netlify-cms-backend-gitlab": "^2.0.0",
"netlify-cms-backend-test": "^2.0.0",
"netlify-cms-core": "^2.0.0",
"netlify-cms-editor-component-image": "^2.0.0",
"netlify-cms-media-library-cloudinary": "^1.0.0",
"netlify-cms-media-library-uploadcare": "^0.3.0",
"netlify-cms-widget-boolean": "^2.0.0",
"netlify-cms-widget-date": "^2.0.0",
"netlify-cms-widget-datetime": "^2.0.0",
"netlify-cms-widget-file": "^2.0.0",
"netlify-cms-widget-image": "^2.0.0",
"netlify-cms-widget-list": "^2.0.0",
"netlify-cms-widget-map": "^1.0.0",
"netlify-cms-widget-markdown": "^2.0.0",
"netlify-cms-widget-number": "^2.0.0",
"netlify-cms-widget-object": "^2.0.0",
"netlify-cms-widget-relation": "^2.0.0",
"netlify-cms-widget-select": "^2.0.0",
"netlify-cms-widget-string": "^2.0.0",
"netlify-cms-widget-text": "^2.0.0",
"prop-types": "^15.7.2",
"react-immutable-proptypes": "^2.1.0"
},
"peerDependencies": {
"react": "^16.8.1",
"react-dom": "^16.8.1"
}
} |
Preview proposed changes to netlifycms.org in the link below: Built with commit c9a9aea |
Parcel bundle exampleAlthough the build for parcel takes longer than I would like. The bundle size is acceptable and there is a very easy setup to consume the libraries as dependencies and build a working example of a |
Rollup bundle exampleRollup sees the bundles as external UMD correctly and expects the library bundles would have to be included into a project as external libraries (same as the script imports example). To create a single bundle, there would need to be an ES module build where there is a module field (pkg.module). Rollup holds true to the standard module specs. _Summary: _ Rollup would need to use the script imports until we get the solution for an ES module build. Otherwise you would just use the example given for script imports of the umd builds. |
# Conflicts: # package.json # packages/netlify-cms-backend-bitbucket/package.json # packages/netlify-cms-backend-git-gateway/package.json # packages/netlify-cms-backend-github/package.json # packages/netlify-cms-backend-gitlab/package.json # packages/netlify-cms-backend-test/package.json # packages/netlify-cms-core/package.json # packages/netlify-cms-editor-component-image/package.json # packages/netlify-cms-lib-auth/package.json # packages/netlify-cms-lib-util/package.json # packages/netlify-cms-media-library-cloudinary/package.json # packages/netlify-cms-media-library-uploadcare/package.json # packages/netlify-cms-ui-default/package.json # packages/netlify-cms-widget-boolean/package.json # packages/netlify-cms-widget-date/package.json # packages/netlify-cms-widget-date/src/index.js # packages/netlify-cms-widget-datetime/package.json # packages/netlify-cms-widget-datetime/src/DateTimeControl.js # packages/netlify-cms-widget-datetime/src/index.js # packages/netlify-cms-widget-file/package.json # packages/netlify-cms-widget-image/package.json # packages/netlify-cms-widget-list/package.json # packages/netlify-cms-widget-map/package.json # packages/netlify-cms-widget-markdown/package.json # packages/netlify-cms-widget-number/package.json # packages/netlify-cms-widget-object/package.json # packages/netlify-cms-widget-relation/package.json # packages/netlify-cms-widget-relation/src/__tests__/relation.spec.js # packages/netlify-cms-widget-select/package.json # packages/netlify-cms-widget-string/package.json # packages/netlify-cms-widget-text/package.json # packages/netlify-cms/package.json # packages/netlify-cms/src/widgets.js # yarn.lock
@erquhart Moved in the latest breaking changes. I hope we can get this in under alpha with these last changes. In this refactor, I changed the names to match the API change in all the widgets, so it will be ready for the refactor and match the naming.
I like the no breaking API change. Seems like a solid way to register a widget. |
Summary
Would allow us to build the
netlify-cms.js
bundle from the umd buld (~+200k overhead added), but we can save that 200k by going direct to the code since we are handling the transforms and plugins within the base webpack monorepo setup anyway.Test plan
netlify-cms
Make sure the
netlify-cms.js
bundle is working correctly (full tests).Make sure all tests are running correctly.
Make sure all development workflow works correctly.
others:
netlify-cms-
Run a development server with all script imports like the following example and make sure they run without a bundle:
[Demo] of the above builds using this PR 馃敟
Detail
What this PR accomplishes
These build improvements fix the
umd
bundles in the monorepo for each library.The current UMD target builds are broken. If you wanted to import from one of the monorepo published libraries and access them through an import, they would fail. It is the major reason we are using the code directly in the
netlify-cms
bundle.There are 2 targets for a
umd
UMD (Universal Module Definition) library:<script src="/cms/netlify-cms-widget-image/dist/umd/index.js"></script>
This allows you to access window.NetlifyCmsWidgetImage in this case from the browser. (think React)
This allows you to access the exports of the module
import { Control, Preview } from 'netlify-cms-widget-image'
We are deriving the
NetlifyCmsWidgetImage
global namespace by using the library name, stripping the-
and Capitalizing each section. This allows us to use webpack's bundler to name the umd export and be able to have them targeted within the modules for export globally.The format in the above
others
:netlify-cms-
test case above is a valid example of bringing the whole CMS into the browser without bundling, it is only a side affect of the builds, and allows for testing the builds, It would be recommended to create your own bundle from the libraries using a package manager. This way you have a managed set of code you can use to build a smaller bundle of thenetlify-cms
with targeted module versions.Example
A
netlify-cms
bundle using:Notes:
and includes the dependencies needed for your module.
Make sure to include React, ReactDOM in your bundle or
make them peer dependencies if you can import your library into a React app.
build note: size of bundle: 2.95 MiB vs 3.41 MiB
Thoughts about why this is Imperative!
netlify-cms.js
with React and ReactDOM as peer dependencies.netlify-cms.js
default bundle, but allow developers to control the size of their cms bundle size.