Gathering detailed insights and metrics for babel-plugin-universal-import
Gathering detailed insights and metrics for babel-plugin-universal-import
Gathering detailed insights and metrics for babel-plugin-universal-import
Gathering detailed insights and metrics for babel-plugin-universal-import
npm install babel-plugin-universal-import
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
115 Stars
152 Commits
41 Forks
5 Watching
27 Branches
18 Contributors
Updated on 07 Nov 2024
JavaScript (100%)
Cumulative downloads
Total Downloads
Last day
41.1%
3,926
Compared to previous day
Last week
-11.7%
22,494
Compared to previous week
Last month
6.6%
96,951
Compared to previous month
Last year
6.6%
1,106,598
Compared to previous year
1
1
25
yarn add babel-plugin-universal-import
.babelrc:
1{ 2 "plugins": ["universal-import"] 3}
Taking from the test snapshots, it does this:
1import universal from 'react-universal-component' 2const UniversalComponent = universal(import('./Foo.js')) 3 4<UniversalComponent /> 5 6 ↓ ↓ ↓ ↓ ↓ ↓ 7 8import universal from 'react-universal-component' 9import universalImport from 'babel-plugin-universal-import/universalImport.js' 10import path from 'path' 11 12const UniversalComponent = universal(universalImport({ 13 chunkName: () => 'Foo', 14 path: () => path.join(__dirname, './Foo.js'), 15 resolve: () => require.resolveWeak('./Foo.js'), 16 load: () => Promise.all([ 17 import( /* webpackChunkName: 'Foo' */ './Foo.js') 18 ]).then(proms => proms[0]) 19})) 20 21<UniversalComponent />
And if you're using dynamic imports:
1import universal from 'react-universal-component' 2const UniversalComponent = universal(props => import(`./${props.page}`)) 3 4<UniversalComponent page='Foo' /> 5 6 ↓ ↓ ↓ ↓ ↓ ↓ 7 8import universal from 'react-universal-component' 9import universalImport from 'babel-plugin-universal-import/universalImport.js' 10import path from 'path' 11 12const UniversalComponent = universal(props => universalImport({ 13 chunkName: props => props.page, 14 path: props => path.join(__dirname, `./${props.page}`), 15 resolve: props => require.resolveWeak(`./${props.page}`), 16 load: props => Promise.all([ 17 import( /* webpackChunkName: '[request]' */ `./${props.page}`) 18 ]).then(proms => proms[0]) 19})); 20 21<UniversalComponent page='Foo' />
NOTE: if you aren't using
react-universal-component
and you just want to serve CSS chunks from extract-css-chunks-webpack-plugin, its not a problem! extract-css-chunks is completely standalone and fully HMR
It names all your chunks using magic comments (see webpack documentation on magic comments) 🔮 behind the scenes and is derived from the imported file. This works with both static and dynamic import paths, as you can see above.
Otherwise, what it's doing is providing all the different types of requires/paths/imports/etc needed by tools like react-universal-component to universally render your component.
The targeted use-case for all this is dynamic imports where you can pass a page
prop to the resulting component, thereby allowing you to create one <UniversalComponent page={page} />
for a large number of your components. This is a major upgrade to the previous way of having to make a hash of a million async components in a wrapping component. You no longer have to think about Universal Components as anything different than your other components that use simple HoCs.
And maybe even cooler to some: you don't have to do universal(() => import())
. I.e. you don't have to wrap it in a function any longer when using react-universal-component
, similar to dynamic(import())
in Next.js...unless of course you're making use of the extremely useful props
argument.
If you can't use babel, you can either copy what this plugin does above, or you can do a shorter version where you just put the important configuration key/vals on the 2nd options argument to universal
:
1import universal from 'react-universal-component' 2 3const load = props => Promise.all([ 4 import( /* webpackChunkName: '[request]' */ `./${props.page}`) 5 ]).then(proms => proms[0]) 6 7const UniversalComponent = universal(load, { 8 chunkName: props => props.page, 9 resolve: props => require.resolveWeak(`./${props.page}`) 10});
notice
chunkName
andresolve
as standard options on the 2nd options argument.
If your compiling the server with Babel, set the following option so import()
does not exist in the final compilation result server-side:
1{ 2 "plugins": [ 3 ["universal-import", { 4 "babelServer": true 5 }] 6 ] 7}
To prevent leaking of information, file names are not included in the final output. However, for debugging purposes, you may set the includeFileName
flag option to true. This will include the path to the source file from which the import() is happening to be exposed.
1{ 2 "plugins": [ 3 ["universal-import", { 4 "includeFileName": true 5 }] 6 ] 7}
This plugin supports currying of the following magic comments defiend by Webpack to the transpiled output:
webpackMode
webpackInclude
webpackExclude
webpackIgnore
webpackPreload
webpackPrefetch
In order to pass that on to the output, you must provide each magic comment in it's own comment block, e.g.
1import( 2 /* webpackMode: "lazy" */ 3 /* webpackChunkName: "Foo" */ 4 "./Foo" 5)
Order in which you specify them will not matter, and invalid leading comments will be stripped out. The logic for naming your webpack chunks remains the same if you specify any of these advanced options. Please refer to the webpack documentation for valid values and configurations of each of these settings.
Checkout the rest of the packages in the "Universal" family:
For chunks to be properly created--and since their names are automatically generated for you--you can't have different chunks with the same name, say index
. So instead of import(`./index`)
, make your imports like this: import(`../ComponentFolderA`)
and import(`../ComponentFolderB`)
. Notice you're going back one directory--this allows the chunk name to be generated uniquely even though the entry point file is index.js
for both components. In addition, if in multiple places you import the same module, make sure they both start with the same base directory name. Again, using ..
is your friend. Initial dots and slashes will be stripped from the resulting chunk name.
To the discerning eye, you may be wondering if the return of import()
is still thenable?? It is! However, if you don't call .then
on it, somewhere (perhaps in the components like react-universal-component that you pass it to), then it won't perform the import. Since most of us are using modules, which we need to do something with in the then
callback, that's not a problem. But if you happen to be importing a module that does its own setup, such as attaches something to the window
object, well then you just need to call .then()
to trigger it. That's a rare case these days, which is why we decided to go with the simplicity seen here. And yes, async await works too.
We use commitizen, so run npm run cm
to make commits. A command-line form will appear, requiring you answer a few questions to automatically produce a nicely formatted commit. Releases, semantic version numbers, tags, changelogs and publishing to NPM will automatically be handled based on these commits thanks to semantic-release. Be good.
Reviewing a package's tests are a great way to get familiar with it. It's direct insight into the capabilities of the given package (if the tests are thorough). What's even better is a screenshot of the tests neatly organized and grouped (you know the whole "a picture says a thousand words" thing).
Below is a screenshot of this module's tests running in Wallaby ("An Integrated Continuous Testing Tool for JavaScript") which everyone in the React community should be using. It's fantastic and has taken my entire workflow to the next level. It re-runs your tests on every change along with comprehensive logging, bi-directional linking to your IDE, in-line code coverage indicators, and even snapshot comparisons + updates for Jest! I requestsed that feature by the way :). It's basically a substitute for live-coding that inspires you to test along your journey.
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
Found 3/24 approved changesets -- score normalized to 1
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Reason
86 existing vulnerabilities detected
Details
Score
Last Scanned on 2024-11-25
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More