概要
前回と前々回でSvelteでTypescript + Pug + Sassを使えるようにしました。
今回はタスクランナー兼、ビルドツールのrollupを最適化していきたいと思います。
手順
追加パッケージ
-
postcssでautoprefixerを使用するので追加。 -
.envファイルを読み込むようにするのでdotenvを追加 - 既存のserveを使わずにpluginで行うため、
rollup-plugin-serveを追加
yarn add -D autoprefixer dotenv rollup-plugin-serve
rollup.config.jsにimportする。
import svelte from 'rollup-plugin-svelte';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import livereload from 'rollup-plugin-livereload';
import html from 'rollup-plugin-bundle-html';
import { terser } from 'rollup-plugin-terser';
import postcss from 'rollup-plugin-postcss';
import serve from 'rollup-plugin-serve';
import dotenv from 'dotenv';
import typescript from 'rollup-plugin-typescript2';
import typescriptCompiler from 'ypescript';
import sveltePreprocessor from 'svelte-preprocess';
import autoprefixer from 'autoprefixer';
buildの出力先をdistに変更
以下のパスを./dist変更します
-
output内のfile: './dist/js/bundle.js' -
plugins内の!production && livereload('./dist'),
import svelte from 'rollup-plugin-svelte';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import livereload from 'rollup-plugin-livereload';
import html from 'rollup-plugin-bundle-html';
import { terser } from 'rollup-plugin-terser';
import postcss from 'rollup-plugin-postcss';
import serve from 'rollup-plugin-serve';
import dotenv from 'dotenv';
import typescript from 'rollup-plugin-typescript2';
import typescriptCompiler from 'ypescript';
import sveltePreprocessor from 'svelte-preprocess';
import autoprefixer from 'autoprefixer';
const production = !process.env.ROLLUP_WATCH;
export default {
input: 'src/main.ts',
output: {
sourcemap: true,
format: 'iife',
name: 'app',
file: './dist/js/bundle.js'
},
plugins: [
svelte({
dev: !production,
extensions: [".svelte"],
css: css => {
css.write('./public/build/bundle.css');
},
preprocess: sveltePreprocessor({
scss: true
}),
emitCss: true,
}),
resolve({
browser: true,
dedupe: ['svelte']
}),
postcss({
extract: true
}),
typescript({ typescript: typescriptCompiler }),
commonjs(),
!production && serve(),
!production && livereload('./dist'),
production && terser()
],
watch: {
clearScreen: false
}
};
function serve() {
let started = false;
return {
writeBundle() {
if (!started) {
started = true;
require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
stdio: ['ignore', 'inherit', 'inherit'],
shell: true
});
}
}
};
}
svelte
rollup-plugin-svelteは既に入ってると思うので、修正方法のみ。
今はbuild後のファイルがすべてbuildディレクトリに入るので、JSとCSSを分離します。
-
cssの出力先をpublic/buildではなく、dist/cssディレクトリにする -
cssをfalseにする-
svelteでCSSの出力を行わないようにする -
emitCssをtrueにしておくことで、別のプラグインにCSS出力を移譲する。(今回はpostcssに移譲)
-
svelte({
dev: !production,
css: false
preprocess: sveltePreprocessor(),
emitCss: true
}),
html
index.htmlをsrcディレクトリから取得してdistにコピーするようにします。
yarn add -D rollup-plugin-bundle-html
-
templateにコピー元のindex.htmlを指定する -
destに出力先のディレクトリを指定する -
filenameに出力後のファイル名を指定する
html({
template: "src/index.html",
dest: "dist",
filename: "index.html"
}),
distに出力されるHTMLは少し加工されます。
<!DOCTYPE html>
<html lang="jp">
<head>
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width,initial-scale=1'>
<title>Svelte app</title>
<link rel='icon' type='image/png' href='/favicon.png'>
<link rel='stylesheet' href='/global.css'>
</head>
<body/>
</html>
出力後HTMLにはbuildされたbundle.jsとbundle.css"の読み込みパスが自動で差し込まれます。
そのため、コピー元htmlからは外しておきます。
<!DOCTYPE html>
<html lang="jp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Svelte app</title>
<link rel="icon" type="image/png" href="/favicon.png">
<link rel="stylesheet" href="/global.css">
<link rel="stylesheet" href="css/bundle.css">
</head>
<body>
<script type="text/javascript" src="build/bundle.js"></script>
</body></html>
postcss
svelteプラグインでやっていたCSSの出力処理を行います。
-
extractに出力先の./dist/css/bundle.cssを指定します -
sourceMapをtrueにして出力するようにします -
pluginsにautoprefixerを追加します
postcss({
extract: './dist/css/bundle.css',
sourceMap: true,
plugins: [
autoprefixer()
]
}),
resolve&commonjs
今回は特に指定をしないので、どちらも引数はなしにします。
resolve(),
commonjs()
DevelopMode
このアタリは好みの問題ですが、productionをconst production = !process.env.ROLLUP_WATCH;で判定しているので、これを逆にしました。
変数名的にもROLLUP_WATCHってしたくなかったので、developかどうかを判定するように変更します。
まず.envファイルを作成します。
その中にDEVELOP_MODEといいう環境変数を追加して、trueにします。
DEVELOP_MODE=true
次にrollup.config.jsも修正します。
-
const production = !process.env.ROLLUP_WATCH;の削除 -
dotenv.config();の追記 -
svelte()内のdev:をdev:process.env.DEVELOP_MODEに変更 -
plugins部分の切り出し -
serve()やlivereloadなどのdevelopでのみ動くものをif文で切り出し -
function serve()を消して、rollup-plugin-serveを適用
一応どこ直したかをピックアップしましたが、このあとの完成版見てもらったほうが早いと思います。
完成
最終的に出来上がったrollup.config.jsがこちら
import svelte from 'rollup-plugin-svelte';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import livereload from 'rollup-plugin-livereload';
import html from 'rollup-plugin-bundle-html';
import { terser } from 'rollup-plugin-terser';
import postcss from 'rollup-plugin-postcss';
import serve from 'rollup-plugin-serve';
import dotenv from 'dotenv';
import typescript from 'rollup-plugin-typescript2';
import typescriptCompiler from 'typescript';
import sveltePreprocessor from 'svelte-preprocess';
import autoprefixer from 'autoprefixer';
dotenv.config();
const plugins = [
svelte({
dev: process.env.DEVELOP_MODE,
css: false,
preprocess: sveltePreprocessor(),
emitCss: true
}),
html({
template: "src/index.html",
dest: "dist",
filename: "index.html"
}),
postcss({
extract: './dist/css/bundle.css',
sourceMap: true,
plugins: [
autoprefixer()
]
}),
typescript({ typescript: typescriptCompiler }),
resolve(),
commonjs()
]
if (process.env.DEVELOP_MODE) {
plugins.push(
serve({
contentBase: './dist',
open: true
}),
livereload({ watch: "./dist" })
);
} else {
plugins.push(terser({ sourcemap: true }))
}
export default {
input: 'src/main.ts',
output: {
sourcemap: true,
format: 'iife',
name: 'app',
file: './dist/js/bundle.js'
},
plugins,
watch: {
clearScreen: false
}
};
まとめ
今回の最適化でrollupが何やってるのか?とか、各pluginになんの引数渡して、何が設定できるのかの理解を深められました。
Webpackやgulpなどもそんなに詳しくないので、よい勉強になったと思います!
また自分のrollup.config.jsを変更した際には追記すると思います。
参考Github
sveltejs/rollup-plugin-svelte
remaxjs/rollup-plugin-postcss
rollup/rollup-plugin-node-resolve
thgh/rollup-plugin-serve