11
11

More than 3 years have passed since last update.

【Svelte】Svelteでrollupの整理をしてみた【rollup.js】

Last updated at Posted at 2020-03-13

概要

前回前々回でSvelteでTypescript + Pug + Sassを使えるようにしました。
今回はタスクランナー兼、ビルドツールのrollupを最適化していきたいと思います。

手順

追加パッケージ

  • postcssでautoprefixerを使用するので追加。
  • .envファイルを読み込むようにするのでdotenvを追加
  • 既存のserveを使わずにpluginで行うため、rollup-plugin-serveを追加
console
yarn add -D autoprefixer dotenv rollup-plugin-serve

rollup.config.jsにimportする。

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 'ypescript';
import sveltePreprocessor from 'svelte-preprocess';
import autoprefixer from 'autoprefixer';

buildの出力先をdistに変更

以下のパスを./dist変更します

  • output内のfile: './dist/js/bundle.js'
  • plugins内の!production && livereload('./dist'),
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 '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ディレクトリにする
  • cssfalseにする
    • svelteでCSSの出力を行わないようにする
    • emitCsstrueにしておくことで、別のプラグインにCSS出力を移譲する。(今回はpostcssに移譲)
rollup.config.js
        svelte({
            dev: !production,
            css: false
            preprocess: sveltePreprocessor(),
            emitCss: true
        }),

html

index.htmlsrcディレクトリから取得してdistにコピーするようにします。

console
yarn add -D rollup-plugin-bundle-html
  • templateにコピー元のindex.htmlを指定する
  • destに出力先のディレクトリを指定する
  • filenameに出力後のファイル名を指定する
rollup.config.js
        html({
            template: "src/index.html",
            dest: "dist",
            filename: "index.html"
        }),

distに出力されるHTMLは少し加工されます。

コピー元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.jsbundle.css"の読み込みパスが自動で差し込まれます。
そのため、コピー元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">
<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を指定します
  • sourceMaptrueにして出力するようにします
  • pluginsautoprefixerを追加します
rollup.config.js
        postcss({
            extract: './dist/css/bundle.css',
            sourceMap: true,
            plugins: [
                autoprefixer()
            ]
        }),

resolve&commonjs

今回は特に指定をしないので、どちらも引数はなしにします。

rollup.config.js
    resolve(),
    commonjs()

DevelopMode

このアタリは好みの問題ですが、productionconst production = !process.env.ROLLUP_WATCH;で判定しているので、これを逆にしました。
変数名的にもROLLUP_WATCHってしたくなかったので、developかどうかを判定するように変更します。

まず.envファイルを作成します。
その中にDEVELOP_MODEといいう環境変数を追加して、trueにします。

.env
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がこちら

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

11
11
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
11
11