概要
前回と前々回で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