3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Mithril.js + webpack + mitts で ファイル分割、動的ロード。 code splitting!

Last updated at Posted at 2020-06-16

Mithril.js + webpack + mitts で ファイル分割、動的ロード。 code splitting!

SPA (Single Page Application) では ページ数が増えると 最終的なファイルサイズもどんどん増えていきます。
出来上がった アプリケーションを最初にロードさせるときにファイルサイズが大きくて、使う人たちが イライラするのはよろしくありません。

Mithril.js + webpack + mitts を使って必要なときに必要なぺージを動的に読み込むようにしてみましょう。

以下の例は、Page/Page1 は静的に読み込むページですが Page/Page2 は実際に必要になった時に動的に読み込まれます。

import m from 'mithril';
import stream from 'mithril/stream';
import mitts from "mitts";

import Page_Index from "Page/Index";
import Page_Page1 from 'Page/Page1';		// 静的にロードされるページ

// ロード開始~完了までの間に一時的に表示されるページ
const Loading = {
	view(vnode) {
		const { error, retry, pastDelay } = vnode.attrs;
		if (error) {
			return <div>Error! <button onclick={ retry }>Retry</button></div>
		} else if (pastDelay) {
			return <div>Loading...</div>;
		} else {
			return null;
		}
	}
};

// 動的にロードされるページ
const Loadable_Page2 = mitts({
	loader: async ()=>{
		const module = await import(/* webpackChunkName: "Page2" */ 'Page/Page2'); // !!!
		return new module.default();
	},
	loading: Page_Loading,
	m : m,
	stream : stream,
});

m.route(document.body, '/', {
	'/' : { render: ()=>{ return <Page_Index />; } } ,
	'/page1' : { render: ()=>{ return <Page_Page1 />; } } ,
	'/page2' : { render: ()=>{ return <Loadable_Page2 />; } } ,
}

Webpack の webpackChunkName のコツ

import(/* webpackChunkName: "Page2" */ 'Page/Page2') の部分ですが、import() での引数のファイルパスは Webpack でのトランスパイル後のファイルパスではなりません。
そもそも、Webpack で1つのファイルにまとめられてしまえば意味が無い。だから分割 code splitting する。
仮に code splitting で分割できたとしてもトランスパイル後の実際のファイル名は分からない。
この悩みを解決するために webpackChunkName を利用しています。

こうすれば Webpack で 1つのファイルにまとめられずに、 Page/Page2 だけは単体で Webpack され dist/Page2.bundle.js のように出力されます。
同時に パスは /* webpackChunkName: "Page2" */ 'Page/Page2' の部分は 実際のパス dist/Page2.bundle.js 等に Webpack により置換されます。

tsconfig.json では removeComments : false を忘れずに

TypeScript を使用しているときに tsconfig.json では "removeComments" : false にしておく必要が有ります。
そうしないと /* webpackChunkName: ... */ などのパラメータが TypeScript が除去してしまい、Webpack に渡らないから、それを防ぐ必要があります。

tsconfig.json
{
	"compilerOptions": {
		"removeComments" : false,
	}
}

環境

  • "mithril": "2.0.4"
  • "webpack": "4.26.0"
  • "typescript": "4.26.0"
3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?