前振り
タイトルが複雑ですよね。自分でもなんでこんなことせんとアカンの...って気持ちです。
例えば、svgファイルをアプリケーション上で利用したいとします。
通常であればGatsbyやStorybookがデフォルトでurl-loaderやfile-loaderを利用してよしなにしてくれます。
ですが、svgファイルを 別のloaderで処理したい!という時どうする?というのを解決していきたいと思います。
単にwebpack loaderを追加したい!という場合には公式にある通りに進めていけば問題ないです。
https://www.gatsbyjs.com/docs/add-custom-webpack-config/
https://storybook.js.org/docs/react/configure/webpack
Gatsby
まずGatsbyのほうからやっていきます。
公式にあるとおりGatsbyではgatsby-node.js
というファイルからwebpackのconfigを操作できます。
svgファイルのloaderを以下のものに変更したいなら
GitHub - JetBrains/svg-sprite-loader: Webpack loader for creating SVG sprites.
exports.onCreateWebpackConfig = ({actions, getConfig}) => {
const config = getConfig();
config.module.rules = config.module.rules.map(rule => {
if (
rule.test &&
rule.test.toString() === '/\\.(ico|svg|jpg|jpeg|png|gif|webp)(\\?.*)?$/'
) {
return {
...rule,
test: /(\.(ico|jpg|jpeg|png|gif|webp)(\?.*)?$)/,
};
} else {
return rule;
}
});
config.module.rules.push({
test: /\.svg$/,
loader: 'svg-sprite-loader',
});
actions.replaceWebpackConfig(config);
};
のようにすれば動きます。
ポイントは以下になります。
if (
rule.test &&
rule.test.toString() === '/\\.(ico|svg|jpg|jpeg|png|gif|webp)(\\?.*)?$/'
) {
return {
...rule,
test: /(\.(ico|jpg|jpeg|png|gif|webp)(\?.*)?$)/,
};
}
渡されたtestフィールドでsvgファイルが該当するようになるloaderから愚直にsvgが該当にならないようにします。
その上で新しく入れ替えたいloaderを利用する宣言をしています。
ずいぶん力業だな〜。と私は思っちゃいましたが
svg-sprite-loader
をgatsby-pluginとして読み込む
GitHub - stldo/gatsby-plugin-svg-sprite-loader: Gatsby plugin for creating SVG sprites using SVG sprite loader
でも同じことしていました。なので私は採用しちゃいました。
gatsby-plugin-svg-sprite-loader/gatsby-node.js at master · stldo/gatsby-plugin-svg-sprite-loader · GitHub
Storybookの場合
察しの良い、ここまで読んでくださった人ならもうお分かりだと思いますが、Storybookでも同じような手順で入れ替えられます。
Storybookの場合は.storybook/main.js
でwebpackのconfigが操作できます。
module.exports = {
stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
addons: [],
webpackFinal: config => {
config.module.rules = config.module.rules.map(rule => {
if (test &&
test.toString() === '/\\.(ico|svg|jpg|jpeg|png|gif|webp)(\\?.*)?$/')
{
return { ...rule, test: /(\.(ico|jpg|jpeg|png|gif|webp)(\?.*)?$)/ }
} else {
return rule
}
})
config.module.rules.push({
test: /\.svg$/,
loader: 'svg-sprite-loader',
});
return config;
},
};
GatsbyとStorybookに限らず、webpackを利用しているツールでは
webpackを操作するポイントさえどうにでもloaderが入れ替えできるよ。というのがわかりましたね。
めでたしめでたし。