tag:crieit.net,2005:https://crieit.net/tags/terser-webpack-plugin/feed
「terser-webpack-plugin」の記事 - Crieit
Crieitでタグ「terser-webpack-plugin」に投稿された最近の記事
2020-11-24T23:34:09+09:00
https://crieit.net/tags/terser-webpack-plugin/feed
tag:crieit.net,2005:PublicArticle/16236
2020-11-24T23:34:09+09:00
2020-11-24T23:34:09+09:00
https://crieit.net/posts/gulp4-webpack5-terser-webpack-plugin-error-resolutions-20201124
続・ Gulp 4 + Webpack 5 を試す (resolutions 使用)
<p>以前、<a href="https://crieit.net/posts/gulp4-webpack5-terser-webpack-plugin-error-20201020">Gulp 4 + Webpack 5 を試す ( 未完 / terser-webpack-plugin で TypeError: Cannot read property ‘javascript’ of undefined エラーになる)</a>の記事で Gulp 4 + Webpack 5 の実験をしましたが、その続きです。</p>
<h2 id="経緯"><a href="#%E7%B5%8C%E7%B7%AF">経緯</a></h2>
<p><a href="https://crieit.net/posts/backstopjs-test-20201122">BackstopJS を試す (Error: Failed to launch the browser process! エラー発生→ puppeteer のバージョンを指定して解決)</a>で <code>package.json</code> に <code>resolutions</code> を記述して Yarn で内部依存パッケージのバージョンを強制的に変更する手法を取りましたが、同様の手法が使えるのではないか、と思った次第です。</p>
<h2 id="検証"><a href="#%E6%A4%9C%E8%A8%BC">検証</a></h2>
<h3 id="package.json"><a href="#package.json">package.json</a></h3>
<p>```json:package.json<br />
// 略<br />
"devDependencies": {<br />
// 略<br />
"webpack": "^5.6.0",<br />
"webpack-stream": "^6.1.1",<br />
"terser-webpack-plugin": "^5.0.3",<br />
// 略<br />
},<br />
"resolutions": {<br />
"webpack": "^5.6.0"<br />
},<br />
// 略</p>
<pre><code><br />上述のように `resolutions` で Webpack のバージョンを指定。
### gulp/tasks/js.js
`gulp/tasks/js.js` は前回のまま。
### webpack.config.js
`webpack.config.js` は source map のための設定を追加した以外はそのままです。
```javascript:webpack.config.js
const _ = require('./gulp/plugin');
const dir = require('./gulp/dir');
const mode = () => {
return process.env.DEV_MODE === 'dev' ? 'development' : 'production';
};
const modeFlag = () => {
return process.env.DEV_MODE === 'dev' ? false : true;
};
const entry = () => {
const entries = _.glob
.sync(
'**/*.js',
{
ignore: [
'_plugins/**'
],
cwd: dir.src.js
}
)
.map(function (key) {
return [key, _.path.resolve(dir.src.js, key)];
});
return Object.fromEntries(entries)
};
const configs = {
mode: mode(),
entry: entry(),
output: {
filename: '[name]'
},
optimization: {
minimizer: [
new _.webpackTerser({
extractComments: 'some',
terserOptions: {
compress: {
drop_console: modeFlag(),
},
},
}),
],
}
};
if (process.env.DEV_MODE === 'dev') { // 追加
configs.devtool = 'inline-source-map';
}
module.exports = configs;
</code></pre>
<p>これで <code>yarn restart</code> などすると</p>
<pre><code class="bash">$ gulp
# 略
[hh:ii:ss] asset app.js 226 KiB [emitted] [minimized] (name: app.js) 1 related asset
webpack 5.6.0 compiled successfully
[hh:ii:ss] Finished 'jsBuild' after 20 s
</code></pre>
<p>動きました!</p>
<hr />
<p>後々は <code>resolutions</code> なしでも動くようにしたいですが、ひとまず動く形になったのでメモしておきます。</p>
<h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2>
<h3 id="Yarn の reasolutions"><a href="#Yarn+%E3%81%AE+reasolutions">Yarn の reasolutions</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://nju33.com/yarn/resolutions%20%E3%81%A7%E4%BE%9D%E5%AD%98%E3%81%AE%E4%BE%9D%E5%AD%98%E3%81%AE%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%82%92%E6%8C%87%E5%AE%9A%E3%81%99%E3%82%8B">yarn: resolutions で依存の依存のバージョンを指定する - nju33</a></li>
</ul>
arm-band
tag:crieit.net,2005:PublicArticle/16235
2020-11-24T23:28:18+09:00
2022-02-25T22:47:24+09:00
https://crieit.net/posts/gulp4-webpack5-terser-webpack-plugin-error-20201020
Gulp 4 + Webpack 5 を試す ( 未完 / terser-webpack-plugin で TypeError: Cannot read property 'javascript' of undefined エラーになる)
<p>以前、<a target="_blank" rel="nofollow noopener" href="https://labor.ewigleere.net/2020/10/06/browserify-babelify-gulp-transpile-ie/">browserify + babelify + Gulp で IE11対応を試す</a>の記事で browserify + babelify を試しましたが、今回は Webpack に挑んでみます。</p>
<p>ただし、プレーンな Gulp 環境ではなく、 <a target="_blank" rel="nofollow noopener" href="https://github.com/arm-band/kiribi_ususama/tree/8a06ef719725236c26337a71bb2b1f9b64ef0900">Ususama</a> で。</p>
<h2 id="コード"><a href="#%E3%82%B3%E3%83%BC%E3%83%89">コード</a></h2>
<h3 id="package.json"><a href="#package.json">package.json</a></h3>
<pre><code class="json">// 略
"devDependencies": {
// 略
"glob": "7.1.6",
"webpack": "^5.1.3",
"webpack-stream": "^6.1.0",
"terser-webpack-plugin": "^5.0.0",
// 略
}
// 略
</code></pre>
<p><code>gulp-uglify-es</code> と <code>gulp-concat</code> を除き、代わりに <code>webpack</code> 本体と Gulp で Webpack を使用するために必要な <code>webpack-stream</code> 、そして minifier の terser の Webpack 用プラグインである <code>terser-webpack-plugin</code> を追加。</p>
<h3 id="gulp/tasks/js.js"><a href="#gulp%2Ftasks%2Fjs.js">gulp/tasks/js.js</a></h3>
<pre><code class="javascript">const gulp = require('gulp');
const plumber = require('gulp-plumber');
const notify = require('gulp-notify');
const webpack = require('webpack');
const webpackStream = require('webpack-stream');
const rename = require('gulp-rename');
const dir = {
dist: {
js: './dist/js'
}
};
const webpackConfig = require('../../weppack.config');
const jsBuild = () => {
return _.webpackStream(webpackConfig)
.pipe(_.plumber({
errorHandler: _.notify.onError({
message: 'Error: <%= error.message %>',
title: 'jsLibBuild'
})
}))
.pipe(_.rename((path) => {
path.basename += '.min'
path.extname = '.js'
}))
.pipe(_.gulp.dest(dir.dist.js));
};
module.exports = jsBuild;
</code></pre>
<h3 id="webpack.config.js"><a href="#webpack.config.js">webpack.config.js</a></h3>
<pre><code class="javascript">const webpack = require('webpack');
const webpackTerser = require('terser-webpack-plugin');
const path = require('path');
const glob = require('glob');
const dotenv = require('dotenv').config();
const dir = {
src: {
js: './src/js'
}
};
const mode = () => {
return process.env.DEV_MODE === 'dev' ? 'development' : 'production';
};
const modeFlag = () => {
return process.env.DEV_MODE === 'dev' ? false : true;
};
const entry = () => {
const entries = _.glob
.sync(
'**/*.js',
{
ignore: [
'_plugins/**'
],
cwd: dir.src.js
}
)
.map(function (key) {
return [key, _.path.resolve(dir.src.js, key)];
});
return Object.fromEntries(entries)
};
module.exports = {
mode: mode(),
entry: entry(),
output: {
filename: '[name]'
},
optimization: {
minimizer: [
new _.webpackTerser({
extractComments: 'some',
terserOptions: {
compress: {
drop_console: modeFlag(),
},
},
}),
],
}
};
</code></pre>
<p>いくつかの記事を参考にしながらタスクを組みます。</p>
<p>自分でカスタマイズした部分は以下。</p>
<ul>
<li><code>.env</code> で <code>dev</code>, <code>demo</code>, <code>prod</code> のモードを切り替えているので、その部分を <code>process.env.DEV_MODE</code> で振り分け
<ul>
<li>Webpack の設定の <code>mode</code> と <code>terser-webpack-plugin</code> の <code>drop_console</code> のフラグが関係しています</li>
</ul></li>
<li>複数の <code>.js</code> ファイルをエントリポイントにしたかったのでその部分は<a target="_blank" rel="nofollow noopener" href="https://qiita.com/masato_makino/items/7130bbe408ca929e7f0d">webpackのentryファイルを複数指定、globパッケージの使い方 - Qiita</a>を参考に</li>
<li>最終的なファイル名は <code>XXX.min.js</code> の形にしたかったので <code>gulp-rename</code> を通しました</li>
</ul>
<h2 id="jQuery の扱い"><a href="#jQuery+%E3%81%AE%E6%89%B1%E3%81%84">jQuery の扱い</a></h2>
<p>タスク自体は上記のやり方で走ることが確認できました( <code>DEV_MODE=dev</code> )。</p>
<p>次は現時点ではまだ jQuery を使用しているので、 jQuery をどう読み込ませるかが課題ですが、以下のようにして動作することを確認しました。</p>
<h3 id="app.js"><a href="#app.js">app.js</a></h3>
<pre><code class="javascript">import $ from 'jquery';
import 'jquery.easing/jquery.easing';
$(() => {
/* 処理 */
});
</code></pre>
<h3 id="sitesearch.js"><a href="#sitesearch.js">sitesearch.js</a></h3>
<pre><code class="javascript">import $ from 'jquery';
import List from 'list.js';
//サイト内検索
export default () => {
const options = {
valueNames: ['searchTitle', 'searchText'],
};
const searchList = new List('listSearch', options);
//hits
searchList.on('searchComplete', function (a) {
$('#hits').text(a.matchingItems.length);
});
};
</code></pre>
<p>サイト内検索で <a target="_blank" rel="nofollow noopener" href="https://listjs.com">List.js</a> を使用しているのですが、これについては<a target="_blank" rel="nofollow noopener" href="https://github.com/javve/list.js/issues/559">How am I suppose to import list.js with es6 and webpack ? · Issue #559 · javve/list.js</a>の Issues の方法で解決しました。</p>
<p>ここまでは比較的順調でした。</p>
<p>しかし、間も無く壁に突き当たることになります……。</p>
<h2 id="TypeError: Cannot read property 'javascript' of undefined エラー"><a href="#TypeError%3A+Cannot+read+property+%27javascript%27+of+undefined+%E3%82%A8%E3%83%A9%E3%83%BC">TypeError: Cannot read property 'javascript' of undefined エラー</a></h2>
<p><code>DEV_MODE=dev</code> で動作することは確認できたので、 <code>DEV_MODE=prod</code> に切り替えました。</p>
<p>すると、以下のエラーが出てしまいました。</p>
<pre><code>TypeError: Cannot read property 'javascript' of undefined
at PATH\TO\PROJECT\node_modules\terser-webpack-plugin\dist\index.js:366:38
</code></pre>
<p><code>DEV_MODE=dev</code> に戻すと先ほどと同じように問題なく動作。上記でこのフラグが関係するのは <code>mode</code> と <code>terser-webpack-plugin</code> の <code>drop_console</code> の2箇所なので、そのどちらかだろうとアタリを付けます。</p>
<p>試しに <code>drop_console</code> を常に <code>false</code> としましたが、 <code>DEV_MODE=prod</code> でエラーは再現しました。</p>
<p>となると、 <code>mode</code> の方ということになります。</p>
<p>ここでエラー文で検索すると、以下の Issues を発見。 <code>terser-webpack-plugin</code> 本家のリポジトリです。</p>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://github.com/webpack-contrib/terser-webpack-plugin/issues/335">TypeError: Cannot read property 'javascript' of undefined ・ Issue #335 ・ webpack-contrib/terser-webpack-plugin</a></li>
</ul>
<p>発生個所も含めてエラー文が同じです。</p>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://github.com/webpack-contrib/terser-webpack-plugin/issues/335#issuecomment-709997726">TypeError: Cannot read property 'javascript' of undefined · Issue #335 · webpack-contrib/terser-webpack-plugin</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://github.com/webpack-contrib/terser-webpack-plugin/issues/335#issuecomment-710004332">TypeError: Cannot read property 'javascript' of undefined ・ Issue #335 ・ webpack-contrib/terser-webpack-plugin</a></li>
</ul>
<p>別の方のコメントを見ると、原因は以下の模様。</p>
<ul>
<li>terser-webpack-plugin 5 は Webpack 4 とは互換性がない</li>
<li><code>webpack-stream</code> の内部で使用している Webpack がバージョン 4 系</li>
</ul>
<blockquote>
<p>yep, we are working on it, release with fix will be today/tomorrow</p>
<p><a target="_blank" rel="nofollow noopener" href="https://github.com/webpack-contrib/terser-webpack-plugin/issues/335#issuecomment-710032380">TypeError: Cannot read property 'javascript' of undefined ・ Issue #335 ・ webpack-contrib/terser-webpack-plugin</a> (2020/10/16日 22:04 JST)</p>
</blockquote>
<p>わりとタイムリーなものを踏んでしまったようなので、 fixed されるのを待つ感じですかね……。</p>
<h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2>
<h2 id="Gulp + Webpack"><a href="#Gulp+%2B+Webpack">Gulp + Webpack</a></h2>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/tonkotsuboy_com/items/2d4f3862e6d05dc0bea1">Gulpで始めるwebpack 4入門 - Qiita</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/am10/items/2516fa04def815195ffe">gulp + webpack + babelをつかってみた - Qiita</a></li>
</ul>
<h3 id="webpack-stream"><a href="#webpack-stream">webpack-stream</a></h3>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://www.npmjs.com/package/webpack-stream">webpack-stream - npm</a></li>
</ul>
<h2 id="Webpack, 複数エントリポイントとoutput"><a href="#Webpack%2C+%E8%A4%87%E6%95%B0%E3%82%A8%E3%83%B3%E3%83%88%E3%83%AA%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88%E3%81%A8output">Webpack, 複数エントリポイントとoutput</a></h2>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/masato_makino/items/7130bbe408ca929e7f0d">webpackのentryファイルを複数指定、globパッケージの使い方 - Qiita</a></li>
</ul>
<h2 id="List.js import"><a href="#List.js+import">List.js import</a></h2>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://github.com/javve/list.js/issues/559">How am I suppose to import list.js with es6 and webpack ? · Issue #559 · javve/list.js</a></li>
</ul>
<h2 id="terser-webpack-plugin"><a href="#terser-webpack-plugin">terser-webpack-plugin</a></h2>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://github.com/webpack-contrib/terser-webpack-plugin/issues/335">TypeError: Cannot read property 'javascript' of undefined ・ Issue #335 ・ webpack-contrib/terser-webpack-plugin</a></li>
</ul>
arm-band