๐ฆ React ๊ฐ์ ธ์จ ๊ตฌ์ฑ ์์ v6
Long story short - nobody cares about version 1 and 2 - by that time the library, I am going to talk about, even had a different name. Version 3 never existed and the difference between 4 and 5 was a
forwardRef
, or React 16 support, which is a good reason for a breaking change. So, in short, v6 is actually 3rd iteration on the API.
๋ฒ์ 6์ผ๋ก ์ ๊ทธ๋ ์ด๋ํ๋ ๊ฒ๋ ์๋ก์ด React ๊ธฐ๋ฅ์ ์ํด ๊ตฌ๋๋ฉ๋๋ค.์ด๋ฒ์๋ ๊ฐ๊ณ ๋ฆฌ๋ฅผ ํตํด React ๊ฐ์ ธ์ค๊ธฐ ๊ตฌ์ฑ ์์๋ฅผ ๊ณต๊ฐ ๊ฐ๊ณ ๋ฆฌ API๋ฅผ ๊ฐ์ง ์ฒซ ๋ฒ์งธ ์ฝ๋ ๋ถํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ Create React App๊ณผ ํธํ๋๋ ์ฒซ ๋ฒ์งธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ๋ง๋ค์์ต๋๋ค. ์ด๊ฒ์ babel ๋งคํฌ๋ก์ ์ง์ ๋๋ถ์ ๋๋ค.
๊ทธ๋ง, ๊ทธ๋ง, ์ ๊ฒ์ผ๋ฅด์ง ์์?
์๋ฒ ์ธก ๋ ๋๋ง, ์ถ์ ๋ฐ ๊ณ ๊ธ API๋ค์์ ๋น๊ต ํ ์ด๋ธ์ ๋๋ค.
์ค๋นํ์ด๋ฐ์ด ๋ค์ด๊ฐ!
ํฐ์นด์ / react ๊ฐ์ ธ์จ ๊ตฌ์ฑ ์์
โ๏ธ๐ฆ๋ฒ๋ค ํ๋ก๊ทธ๋จ๊ณผ ๋ฌด๊ดํ SSR ์น์ ์ฝ๋ ๋ถํ ์๋ฃจ์
๊ฐ์ ธ์จ ๊ตฌ์ฑ ์์โ
์ฝ๋ ๋ฒ์คํธ๋ ํญ์ ์ ํจํฉ๋๋ค*
๋ชจ๋ ํ๋ซํผ๊ณผ ํธํ๋๋ SSR ์น์ํ ์ฝ๋ ๋ถํ
ํ ๋ฒ์ ๊ฐ์ ธ์ค๊ธฐ์์ ๋ ์ข์ ๊ฒฝํ์ ์ ๊ณตํ๋ค
* It's really will never let you down. All credits to your bundler.
๐ Usage | API | Setup | SSR | CCS Concurrent loading | Webpack/Parcel
๋์๊ด
๊ฑฑ์ ํ๋ค
๊ณ ์ฒด ๊ณ์ ๊ธฐ
์ฐ๊ฒฐ
๋์๊ด
๋น๋ชจ๋
๊ฐ์ ธ์ค๊ธฐ(./${value}
)
๋ฐ๋ฒจํผ
์น ํจํค์ง๋ง
๋ฐ์ํ๋ค๊ฒ์ผ๋ฅด๋ค
โ
โ
โ
โ
โ
โ
๐น
๋ฐ์ ๋ก๋ ๊ฐ๋ฅ
โ
โ
โ
โ
โ
โ
โ
๐ฟ
@ ๋ก๋ ๊ฐ๋ฅ/๊ตฌ์ฑ ์์
โ
โ
โ
โ
โ
โ
โ
๐ฟ
๊ฐ์ ธ์จ ๊ตฌ์ฑ ์์
โ
โ
โ
โ
โ
โ
โ
๐ธ
Read more about what this table displays
์ฃผ์ ํน์ง:
* It's really will never let you down. All credits to your bundler.
Read more about what this table displays
์ผ.๏ธโฃ ๋จ์ผ ์ง์ ์ถ์ฒ - ๋น์ ์ ๋ฌถ์๊ธฐ ๊ตฌ๋ ๋ชจ๋
๐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฝ๋ ๋ถํ
๐ก TypeScript ๋ฐ์ธ๋ฉ
โ๏ธ ๋ฐ์ํ๋คLazy Underground(ํซ ๋ชจ๋ ์ ๋ฐ์ดํธ๊ฐ ๋นํ์ฑํ๋ ๊ฒฝ์ฐ)
๐ ํด๋ผ์ด์ธํธ ๋น๋๊ธฐํ, ์๋ฒ ๋๊ธฐํ.์์คํ์ค ์ง์(
View on GitHub
๊ฐ์ ธ์จ ์ฐ๊ฒฐ ์ฌ์ฉ
์ง์ฐ ์ ์ฌ๋
React.lazy
๊ณผ Components
์ ๊ดํ ๊ฒ์ด ์๋๋ผ ์ด๋ ํ ๋ณ์ฒด ๋ค์๋ ๋์ import
๋ง ์์ ๋ฟ, ์ ๋ ๋ชจ๋ ๊ฒ์ ์ ์ฌํ ์ ์๋ค.๋ง์ดํธ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐ ํ์ํ ๊ฒ์ ์ ๋นํ ๋ฐ์ ์ง์ ์ผ ๋ฟ์
๋๋ค.// a STATIC table with imports
const languages = {
'en': () => import('./i18n/en'), // it's probably a json...
'de': () => import('./i18n/de'),
}
// just a helper function
const pickLanguage = (lng) => languages[lng];
// your component
const MyI18nProvider = ({lng, children}) => {
// let's pick and provide correct import function for our language
const {
imported: messages = {} // defaulting to empty object
} = useImported(pickLanguage(lng));
// set messages to the Provider
return <I18nProvider value={messages}>{children}</I18nProvider>
}
๊ทธ๊ฒ ๋ค์ผ.์ ์ผํ ๋ฌธ์ ๋ ๊ธฐ๋ณธ {}
์ด ๋ชจ๋ ๋ ๋๋ง์์ ์ ์ผํ๊ธฐ ๋๋ฌธ์ ์ด ๊ตฌ์ฑ ์์ ์ด์ธ์ ๋จ๋
๋ณ์๋ก ์ถ์ถํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ข๋ค.ํ์ง๋ง ์ด๊ฒ์ ๋ค๊ฐ ๊ฑฑ์ ํด์ผ ํ ์ผ์ด ์๋๋ค.useImported
์ ์ํ๋ ๋ด์ฉ์ ๋ถ๋ฌ์ฌ ์ ์์ผ๋ฉฐ, react-imported-component
์ด ๊ณต๊ฐํ ๋ค๋ฅธ ๋ชจ๋ API๋ ๊ทธ ์์ ์ธ์์ ธ ์์ต๋๋ค.importedModule ๋ฐ importedModule
useImported
์ ํญ์ ๊ฝ ์ฐฌ ๊ฒ์ด ์๋๋ผ ๋๋ก๋ ๋์ฑ ์ฑ๋ช
์ ์ธ ๋ด์ฉ์ ์ ํํ ์ ์๋ค.๋ฐ๋ผ์reactrenderprops ์ธํฐํ์ด์ค๋ฅผ ํตํด ์ํ๋ ๋ด์ฉ์ ๊ฐ์ ธ์ฌ ์ ์๋ ์กฐ์๊ฐ ์์ต๋๋ค.๋๋ถ๋ถ์ ์ฌ๋๋ค์๊ฒ ์ด๋ฐ ๋ชจ๋ธ์ loadable.lib์ผ๋ก ๋ ๋๋ฆฌ ์๋ ค์ ธ ์๋ค.
import {importedModule, ImportedModule} from 'react-imported-component';
// you can use it to codesplit and use `momentjs`, no offence :)
const Moment = importedModule(() => import('moment'));
<Moment fallback="long time ago">
{(momentjs /* default imports are auto-imported*/) => momentjs(date).fromNow()}
</Moment>
// or, again, translations
<ImportedModule
import={() => import('./i18n/en')}
// fallback="..." // will throw to the Suspense boundary without fallback provided
>
{(messages) => <I18nProvider value={messages}>{children}</I18nProvider> }
</ImportedModule>
๊ฐ์ ธ์ค๊ธฐ์ ๊ฒ์ผ๋ฆ
๋ํ ๊ณตํต API-
imported
๋ฐ lazy
๋ ๊ฐ๊ฐ ์์ต๋๋ค.๊ทธ ์ค์์
lazy
์ React.lazy
์ฒ๋ผ ํ๋ฒํ ์์ฌ๋ก ์์ฐ ์ค์ ๊ฒ์ผ๋ฅด๋ค. imported
์ 1์ธ๋ ์ฝ๋ ๋ถํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํธํ๋๋ API๋ก ๊ฐ์ ธ์จ ๋ก์ ์ ํ์ด๋ค.const Component = importedComponent( () => import('./Component'), {
LoadingComponent: Spinner, // what to display during the loading
ErrorComponent: FatalError // what to display in case of error
});
Component.preload(); // force preload
// render it
<Component... />
๋ณ๊ฒ
React ์์ฉ ํ๋ก๊ทธ๋จ ์ง์ ๋ง๋ค๊ธฐ
CRA์ ๊ด๋ จํ์ฌ ๋ค์๊ณผ ๊ฐ์ ์ธ ๊ฐ์ง ์ฌํญ์ ์์์ผ ํฉ๋๋ค.
react-imported-component
์ ์นํฉ์ ์ด๋ค ๊ฒ๋ ํ์ํ์ง ์๊ณ ๋ฌถ์ ํ๋ก๊ทธ๋จ์ ๋
๋ฆฝ์ ์ด๋ฉฐ ์นํฉ ๋งคํฌ๋ก๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ด๊ฒ์ CRA์ ์ ์ผํ ๊ธฐ์กด ๋๊ตฌ์
๋๋ค.react-imported-component/macro
๋ง ์ฌ์ฉํ๋ฉด ์ค๋ ์ฌ๊ธฐ๊น์งimport {imported} from "react-imported-component/macro";
imported(()=>import('./aGoodDay'));
๋ฒ๋ค ๋ ๋ฆฝ์ฑ
์ด๊ฒ์ ์ธ ๊ฐ์ง ๋ค๋ฅธ ์ผ์ ์๋ฏธํ๋ค.
imports
์๋ ์ ์ฉ๋ฉ๋๋ค.์ด๊ฒ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ค์ํ์ง ์๋ค.๋น์ฆ๋์ค ํ๋ก์ธ์ค ๋ก๋ ์ค
์คํฌ๋ฆฝํธ์ ์ฌ์ํ๋ฅผ ์คํํ๋ ์ฒซ ๋ฒ์งธ ๋ฐฉ๋ฒ์ ์ ์ฌ ๊ณผ์ ์ ํจ์จ์ ๋์ด๋ ๊ฒ์ด๋ค.
imported-component
์ ๋จ๋
์
๊ตฌ์ ์ธ /boot
์ ์ ๊ณตํ์ฌ ๋ฉ์ธ ์คํฌ๋ฆฝํธ ํ๊ฐ ์ ์ ์ด๊ธฐํ ๊ณผ์ ์ ์์ํ์ฌ ์ง์ฐ๋ ์คํฌ๋ฆฝํธ๋ฅผ ๋ฏธ๋ฆฌ ๋ถ๋ฌ์ค๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.์ด๊ฒ์ ๋งค์ฐ ์ข์ CRA ๋๋ Parcel ์๋ฃจ์
์
๋๋ค. HTML์ ์ฝ์
ํ ๋ธ๋ก ํ์ผ (์ถ๊ฐ ํ๋ฌ๊ทธ์ธ์ด ์ค์น๋์ด ์์ง ์์) ์ ์ค์ ์ด๋ฆ์ ๋ชจ๋ฅผ ์๋ ์์ต๋๋ค.import "../async-requires";
import {injectLoadableTracker} from "react-imported-component/boot";
// ^ just 1kb
// injects runtime
injectLoadableTracker('importedMarks');
// give browser a tick to kick off script loading
Promise.resolve().then(() =>
Promise.resolve().then(() => {
// the rest of your application
// imported with a little "pause"
require('./main')
})
);
์ด๊ฒ์ ๋งค์ฐ ๊ฐ๋จํ๊ณ ์ฌ๋ฏธ์๋ค. ๋น์ ์ js๋ ํด์๋๊ณ ํ๊ฐ๋์์ง๋ง ์์ ํ ์คํ๋์ง ์์๋ค.๊ทธ๋ฆฌ๊ณ imported
์ ๋ถ๋ฌ์ค๋ ๋ฐ ํ์ํ ๋ธ๋ก์ ํฐ์นํฉ๋๋ค. ๋ถ๋ฌ์ค๋ imports
๋ง ํธ์ถํฉ๋๋ค.๊ทธ๋ฐ ๋ค์ ์์ฉ ํ๋ก๊ทธ๋จ์ด ๊ณ์ ์คํ๋ฉ๋๋ค.์ด ์์ด๋์ด๋ฅผ ์ค๋ช ํ๊ธฐ ์ํด ๋ผ์ดํธํ์ฐ์ค ์ค๋ ์ท ๋ ๊ฐ(4x ๊ฐ์, 3Mb JS ๋ฒ๋ค)๋ฅผ ์ ๊ณตํฉ๋๋ค.
main
์ ์๊ตฌํฉ๋๋ค. ์๊ธฐ์ ๊ฐ์ต๋๋ค.main
์ด ํ์ํ์ง ์์ต๋๋ค. ์๊ธฐ์ ๊ฐ์ด (catch
์ผ๋ก ์ด๋ํ ๋ฟ, ๋ชจ๋ ์ฝ๋๋ ์ฌ์ ํ ๋ฌถ์ฌ ์์ต๋๋ค)์ผ์ชฝ์ ์์'ํ์๋ฐ์ค'์ ๋ธ๋ผ์ฐ์ ์ ๋ํ ๋ง์ดํฌ๋ก ์์ ์ ์ฃผ์ํ์ฌ ์ค๋ฅธ์ชฝ์ ๋คํธ์ํฌ ๋ด์ฉ์ ์์ํ์ญ์์ค.
์ด ํ์๋ฐ์ค๊ฐ ์ผ๋ง๋ ์์์ง ์ฃผ์ํ์ธ์.
์คํฌ๋ฆฝํธ ํ๋ฆฌ๋ก๋์ ํ๋ฆฌํ์น ๊ฐ์ ๋ชจ๋ ์ผ์ ์ค์ํ์ง ์๋ค. - ์คํฌ๋ฆฝํธ๊ฐ ์์ด๋ ๊ทธ๋ ๊ฒ ๋์์ง ์๋ค.๊ทธ๋์ 2์ฐจ ๋ฐ์๊ณผ CRA์ ์์๋ฅผ ์ด๋ฉด ๋ฐ๋ก ์ฌ์ฉํ ์ ์์ ๊ฑฐ์์.
๊น์ด ์๋ ํจํค์ง ํตํฉ
๊ทธ๋ฌ๋ ๊ฐ์ฅ ์ข์ ๊ฒฐ๊ณผ๋ ๋์ฑ ์ธ๋ฆฝ์ ์ธ ๋ฐฉ๋ฒ์ด ํ์ํ๋ค.v6์ ๋ ๋ค๋ฅธ ๋ณํ์ธ ๋จ๋ ์น ํตํฉ ํจํค์ง๊ฐ ๋์์ด ๋ ๊ฒ์ด๋ค.์ด๋ฆ์ด ๋๋ ทํ๋ค.
ํฐ์นด์ / ํจํค์ง ๊ฐ์ ธ์ค๊ธฐ
๐ํต๊ณ ํจํค์ง ํ๋ฌ๊ทธ์ธ ๋ฐ๐ฉ์นํฉflushchunks๊ฐ ์์ด๋ฅผ ๋ณ์์ด์!
ํจํค์ง ๊ฐ์ ธ์ค๊ธฐ
์ฐ๋ฆฌ๋ ์ ํํ ๋ฐฉ์์ผ๋ก ๋์ ์๋ฉ์ด๋ฅผ ์์
ํ ๊ฒ์ด๋ค.
๐ stats-webpack-plugin and ๐ฉ webpack-flush-chunks had a baby!
์๋ฒ ์ธก API
ํจํค์ง ํ๋ฌ๊ทธ์ธ
const {ImportedPlugin} = require('webpack-imported')
module.exports = {
plugins: [
new ImportedPlugin('imported.json')
]
};
ํจํค์ง ํ๋ฌ๊ทธ์ธ
const {ImportedPlugin} = require('webpack-imported') module.exports = { plugins: [ new ImportedPlugin('imported.json') ] };
This will output imported.json
as a one of the emitted assets, with all the information carefully sorted.
Stat.json
If you have only stat.json
generated somehow you can convert into into "imported" format
import {importStats} from "webpack-imported"
import stats from 'build/stats.json'
const importedStat = importStats(stats);
SSR API
-
importedAssets(stats, chunks, [tracker])
- return all assets associated with provided chunks. Could be provided atracker
to prevent duplications between runs. -
createImportedTracker()
- creates a duplication prevention tracker
import {importedAssets} from "webpack-imported"
import importedStat from "build/imported.json";
โฆA webpack plugin to gather the data, and clientside API, including React binding, to handle everything out of the box.
import importedData from 'build/imported.json';
<WebpackImport
stats={importedData}
chunks={getMarkedChunks(marks)}
publicPath={importedData.config.publicPath}
crossOrigin={CDN_ANONYMOUS}
/>
CSS
CSS๋ ๊ฐ์ฅ ์ข์ ๋ฐฉ์์ผ๋ก ์ฒ๋ฆฌ๋๋ค. ์ผ๋ฐ์ ์ธ CSS ํ์ผ์ ์์ด์ ๊ด๊ฑด์ ์ธ ์คํ์ผ ์ถ์ถ์ ์์๋ฅผ ์ด๋ฉด ๋ฐ๋ก ์ฌ์ฉํ ์ ์๋ค.
ํฐ์นด์ / ์ฌ์ฉ ์คํ์ผ
๐ํ์ด์ง๋ฅผ ๋ณด์ฌ์ฃผ๋ ๋ฐ ์ฌ์ฉ๋๋ ๋ชจ๋ ๊ด๊ฑด์ ์ธ ์คํ์ผ์ ๋๋ค.
์ฌ์ฉ ์คํ์ผ
๋ ๋๋ง ํ์ด์ง์ ์ฌ์ฉํ ๋ชจ๋ ์คํ์ผ ๊ฐ์ ธ์ค๊ธฐ
Bundler and framework independent CSS part of SSR-friendly code splitting
์ฃผ์ด์ง HTML ๋ฐ/๋๋ ์ธ๋ผ์ธ ํค ์คํ์ผ์์ ์ฌ์ฉ๋ css
๊ฐ์ ํ์ผ ๊ฐ์ง
๋๊ธฐํ ๋๋ ํ๋ฆ ๋ ๋๋ง์ ์ง์ํฉ๋๋ค.
์ฝ๋ ๋ถํ
์ด๊ฒ์ React๊ฐ ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ฌด๊ดํ๋๋ผ๋ ์ฝ๋ ๋ถํ , ์๋ฒ ์ชฝ ๋ ๋๋ง, React์ ๊ดํ ๊ฒ์
๋๋ค.
์ฝ๋ ๋ถํ ์ ์ข์ ํน์ฑ์ด๊ณ SSR๋ ์ข์ง๋ง ๋น์ ์
ํ์ด์ง๋ฅผ ํ์ฑํํ๊ธฐ ์ ์ ์ฌ์ฉํ๋ ๋ชจ๋ scripts
์ ํด๋ผ์ด์ธํธ์ ๋ก๋ํฉ๋๋ค.
๋ชจ๋๊ฐ ์ด์ผ๊ธฐํ๊ณ ์๋ ๊ฒ์ .css
์ด ์๋๋ผ .js
์ด๋ค.
์ด๊ฒ์ ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ์์ฑ๋ ๊ฒ์ด๋ค.์ด๊ฒ์ ํฐ ์๋ฌด๊ฐ ์๋๋ค. ์ฝ๋๋ก ๋ธ๋ก์ ๋ถํ ํ๊ธฐ๋ง ํ๋ฉด
์ถ์ ํ ์ ์์ต๋๋ค. - ์ฌ์ฉํ๊ณ ์์ผ๋ฉฐ ๊ตฌ์ฑ ์์๊ฐ ๋ด๋ถ์ ์ผ๋ก ์ ์๋์ด ์์ต๋๋ค.
CSS๊ฐ ๋ ์ด๋ ค์์. - ๋๋ค ํด๋์ค๋ง ์ฌ์ฉํ ์ ์์ด์. ๋ค์์์?๋๋...
View on GitHub
ํ๋ฅด๋ค
์ฌ์ฉํ๋ ๋ชจ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์๋ Streamig ์นํ์ ์ธ API๊ฐ ์์ผ๋ฉฐ ์ํ๋ ์ต์์ TTFB๋ฅผ ์ ๊ณตํฉ๋๋ค.
์, ์?
์ฝ๋ ๋ถํ , ์ฝ๋ ๋ถํ , ์ฝ๋ ๋ถํ , JS๋ CSS ๋ฉํ์ ์ต์ ํํ๋ ๋ฐฉ๋ฒ์ ์๊ณ ์ถ๋ค๋ฉด.
โ๏ธ ์ฝ๋ ๋ถํ - ๋ฌด์, ์ธ์ , ์
์๋ ์ฝ๋ฅด์กฐ๋
ธํใป 10์ 4์ผใป 12๋ถ ์ฝ๊ธฐ
#react
#codesplitting
#webdev
๊ฒฐ๋ก
Bundler and framework independent CSS part of SSR-friendly code splitting
โ๏ธ ์ฝ๋ ๋ถํ - ๋ฌด์, ์ธ์ , ์
์๋ ์ฝ๋ฅด์กฐ๋ ธํใป 10์ 4์ผใป 12๋ถ ์ฝ๊ธฐ
Reference
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(๐ฆ React ๊ฐ์ ธ์จ ๊ตฌ์ฑ ์์ v6), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค https://dev.to/thekashey/react-imported-component-v6-4304ํ ์คํธ๋ฅผ ์์ ๋กญ๊ฒ ๊ณต์ ํ๊ฑฐ๋ ๋ณต์ฌํ ์ ์์ต๋๋ค.ํ์ง๋ง ์ด ๋ฌธ์์ URL์ ์ฐธ์กฐ URL๋ก ๋จ๊ฒจ ๋์ญ์์ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ ์ธ ๋ฐ๊ฒฌ์ ์ ๋ (Collection and Share based on the CC Protocol.)
์ข์ ์นํ์ด์ง ์ฆ๊ฒจ์ฐพ๊ธฐ
๊ฐ๋ฐ์ ์ฐ์ ์ฌ์ดํธ ์์ง
๊ฐ๋ฐ์๊ฐ ์์์ผ ํ ํ์ ์ฌ์ดํธ 100์ ์ถ์ฒ ์ฐ๋ฆฌ๋ ๋น์ ์ ์ํด 100๊ฐ์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ํ์ต ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ์ต๋๋ค