Skip to content

Commit

Permalink
Merge pull request #56 from faceyspacey/webpack-4
Browse files Browse the repository at this point in the history
 feat(universal-loader): Webpack 4 Support
  • Loading branch information
ScriptedAlchemy authored Jun 4, 2018
2 parents 348c2b0 + d6bb771 commit 150f52c
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 8,843 deletions.
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# babel-plugin-universal-import maintainers
* @faceyspacey @zackljackson
31 changes: 4 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,14 @@ const UniversalComponent = universal(import('./Foo.js'))

import universal from 'react-universal-component'
import universalImport from 'babel-plugin-universal-import/universalImport.js'
import importCss from 'babel-plugin-universal-import/importCss.js'
import path from 'path'

const UniversalComponent = universal(universalImport({
chunkName: () => 'Foo',
path: () => path.join(__dirname, './Foo.js'),
resolve: () => require.resolveWeak('./Foo.js'),
load: () => Promise.all([
import( /* webpackChunkName: 'Foo' */ './Foo.js'),
importCss('Foo')
import( /* webpackChunkName: 'Foo' */ './Foo.js')
]).then(proms => proms[0])
}))

Expand All @@ -92,30 +90,27 @@ const UniversalComponent = universal(props => import(`./${props.page}`))

import universal from 'react-universal-component'
import universalImport from 'babel-plugin-universal-import/universalImport.js'
import importCss from 'babel-plugin-universal-import/importCss.js'
import path from 'path'

const UniversalComponent = universal(props => universalImport({
chunkName: props => props.page,
path: props => path.join(__dirname, `./${props.page}`),
resolve: props => require.resolveWeak(`./${props.page}`),
load: props => Promise.all([
import( /* webpackChunkName: '[request]' */ `./${props.page}`),
importCss(props.page)
import( /* webpackChunkName: '[request]' */ `./${props.page}`)
]).then(proms => proms[0])
}));

<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](https://github.com/faceyspacey/extract-css-chunks-webpack-plugin), use [babel-plugin-dual-import](https://github.com/faceyspacey/babel-plugin-dual-import) instead.
> NOTE: if you aren't using `react-universal-component` and you just want to serve CSS chunks from [extract-css-chunks-webpack-plugin](https://github.com/faceyspacey/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* 🔮 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](https://github.com/faceyspacey/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.

Perhaps the most powerful part however is that it also attempts to import a separate CSS file along with js chunks for optimum chunk sizes, caching and performance. Look in what `Promise.all` does. To fulfill this mission you must be using [extract-css-chunks-webpack-plugin](https://github.com/faceyspacey/extract-css-chunks-webpack-plugin) to create multiple CSS chunks for dynamic imports.

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.*

Expand All @@ -125,11 +120,9 @@ If you can't use babel, you can either copy what this plugin does above, or you

```js
import universal from 'react-universal-component'
import importCss from 'babel-plugin-universal-import/importCss.js'

const load = props => Promise.all([
import( /* webpackChunkName: '[request]' */ `./${props.page}`),
importCss(props.page)
import( /* webpackChunkName: '[request]' */ `./${props.page}`)
]).then(proms => proms[0])

const UniversalComponent = universal(load, {
Expand All @@ -153,29 +146,13 @@ If your compiling the server with Babel, set the following option so `import()`
}
```

## Supressing console warnings

When navigating across pages, warnings will be displayed to alert you about any potential missing CSS chunks. If you're not using the CSS functionality of this plugin or just want to keep your console clean, use the `disableWarnings` option like so:

```js
{
"plugins": [
["universal-import", {
"disableWarnings": true
}]
]
}
```

## Next Steps

Checkout the rest of the packages in the *"Universal"* family:
- [webpack-flush-chunks](https://github.com/faceyspacey/webpack-flush-chunks)
- [react-universal-component](https://github.com/faceyspacey/react-universal-component)
- [extract-css-chunks-webpack-plugin](https://github.com/faceyspacey/extract-css-chunks-webpack-plugin)

*We realize things are bit confusing right now because of the shear number of packages. The next release is called `universal-render` and will bring everything under one roof, while adding a few final tricks. You heard it here first.*

## Caveat
- 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.**

Expand Down
Loading

0 comments on commit 150f52c

Please sign in to comment.