LoginSignup
7
5

More than 5 years have passed since last update.

transpileOnly trueにしたts-loader でNuxt.jsを書く

Last updated at Posted at 2018-09-07

目的

  • nuxt.jsをtypescriptで書きたい
  • ビルドを高速化するために ts-loaderの transpileOnly: true にしたい
  • ただし型のチェックはしたいので fork-ts-checker-webpack-plugin を使いたい

前提

  • nuxt: 2.3.4
  • もしくは nuxt-edge: ^2.0.0-25598366.31ec2a2

nuxt v2.3.4 版

transpileOnly = true, fork-ts-checker-webpack-plugin の導入

typescript.js を修正します

typescript.js
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin')

module.exports = function() {
  this.extendBuild(config => {
    const tsLoader = {
      loader: 'ts-loader',
      options: {
        appendTsSuffixTo: [/\.vue$/],
        transpileOnly: true // トランスパイルのみの設定をいれる
      },
    };

    ..
    if (config.name === 'client') { // サーバ・クラアイント用両方で型検査する必要はないのでどちらか一方だけ実施
      config.plugins.push(new ForkTsCheckerWebpackPlugin({
        workers: ForkTsCheckerWebpackPlugin.ONE_CPU,
        tslint: true,
        vue: true,
      }));
    }
    ..
  })
}

export 'XXXX' was not found in './path/to/file.ts' を抑止する

開発環境用ビルドの際の抑止

typescript.js を修正します

typescript.js
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin')
// ※1
class IgnoreNotFoundExportPlugin {
  apply(compiler) {
    compiler.hooks.done.tap('warnfix-plugin', (stats) => {
      const messageRegExp = /export '.* was not found in/
      stats.compilation.warnings = stats.compilation.warnings.filter((warn) => {
        if (warn.name === 'ModuleDependencyWarning' && messageRegExp.test(warn.message)) {
          return false
        }
        return true
      })
    })
  }
}

module.exports = function() {
  this.extendBuild(config => {
    ..
    config.plugins.push(new IgnoreNotFoundExportPlugin())
  })
}

本番環境用ビルドの際の抑止

nuxt.config.js を修正します

nuxt.config.js
  build: {
    stats: {
      warningsFilter: /export .* was not found in/,
    }
  }

nuxt-edge 版

webpackの設定をカスタマイズする

transpileOnly = true, fork-ts-checker-webpack-plugin の導入

typescript.js を修正します

typescript.js
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin')

module.exports = function() {
  this.extendBuild(config => {
    const tsLoader = {
      loader: 'ts-loader',
      options: {
        appendTsSuffixTo: [/\.vue$/],
        transpileOnly: true // トランスパイルのみの設定をいれる
      },
    };

    ..
    config.plugins.push(new ForkTsCheckerWebpackPlugin({
      workers: 2, // ここはお好みで
      tslint: true,
      vue: true,
    }));
    ..
  })
}

これで導入完了ですがwebpack4 では https://github.com/TypeStrong/ts-loader/issues/751 でissueにあがっているようにexportのwarningが出てしまうのでノイズを減らすためにこれを抑止します

export 'XXXX' was not found in './path/to/file.ts' を抑止する

開発環境用ビルドの際の抑止

typescript.js を修正します

typescript.js
module.exports = function() {
  this.extendBuild(config => {
    ..
    if (config.entry.app && config.entry.app instanceof Array) {
      // ※1
      config.entry.app = config.entry.app.map((entry) => entry.replace(/webpack-hot-middleware\/client\?/, 'webpack-hot-middleware/client?quiet=true&'));
    }

    // ※2
    const friendlyErrorsWebpackPlugin = config.plugins.find((plugin) => plugin.constructor.name === 'FriendlyErrorsWebpackPlugin');
    if (friendlyErrorsWebpackPlugin) {
      friendlyErrorsWebpackPlugin.logLevel = 2;
    }
    ..
  })
}
  • ※1 開発環境ではhmrを利用していますのでブラウザのconsole.warn に吐かれないように抑止します
    • パラメータ quiet=true を追加します
    • nuxt内では下記のようなコードになっており webpack-hot-middleware に対してオプションを追加できないコードになっているため webpack-hot-middleware/client?webpack-hot-middleware/client?quiet=true& に置換するようにしています(かなり力技)
node_modules/nuxt-edge/dist/nuxt.js
     // Add HMR support
     if (this.options.dev) {
       config.entry.app.unshift(
         // https://github.com/glenjamin/webpack-hot-middleware#config
         `webpack-hot-middleware/client?name=client&reload=true&timeout=30000&path=${
           this.options.router.base
         }/__webpack_hmr`.replace(/\/\//g, '/')
       );
     }
  • ※2 npm run nuxtを実行しているターミナルにwarningが出力されないように抑止します
    • nuxt内では FriendlyErrorsWebpackPlugin というプラグインでエラーメッセージを出力しています. そのログレベルを ERROR に変更します
node_modules/nuxt-edge/dist/nuxt.js
    // Add friendly error plugin
    if (this.options.dev && !this.options.build.quiet) {
      config.plugins.push(
        new FriendlyErrorsWebpackPlugin({
          clearConsole: true,
          logLevel: 'WARNING'
        })
      );
    }
node_modules/@nuxtjs/friendly-errors-webpack-plugin/src/friendly-errors-plugin.js
const logLevels = {
  'INFO': 0,
  'WARNING': 1,
  'ERROR': 2,
  'SILENT': 3
}

本番環境用ビルドの際の抑止

nuxt.config.js を修正します

nuxt.config.js
  build: {
    stats: {
      warningsFilter: /export .* was not found in/,
    }
  }

これで設定は完了です.コードの保存の度に型のチェックとlintが走ります

名称未設定.png

まとめ

  • 最終的な設定ファイルはこちら

  • 自分の環境では transpileOnly: false と比較してビルドの時間が15%くらい短縮されました!

  • nuxt内でどういったwebpackのビルドがされているのかソースを読まないとやりたいことができない場合もありますが,どのようにnuxtがビルドしているかの理解を深めるには良いと思います

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