How to minify gulp-webpack file? - javascript

Have a follow situation:
gulp.task('webpack', function(cb) {
gulp.src('webpack-init.js')
.pipe(webpack({
output: {
filename: 'bundle.js',
},
}))
.pipe(gulp.dest('./client/js'));
cb();
});
All ok, but i want to minify output file.
If i use gulp-uglify directly -
.pipe(webpack(...))
.pipe(uglify().on('error', gutil.log))
.pipe(gulp.dest('./client/js'));
have an error: "Unexpected token: punc ())]" and others of that ilk.

I found a solution. We can use normal version of webpack (not just gulp-webpack) to provide plugin include capability:
var gulpWebpack = require('gulp-webpack'),
webpack = require('webpack');
gulp.task('webpack', function() {
gulp.src('webpack-init.js')
.pipe(gulpWebpack({
output: {
filename: 'bundle.js',
},
plugins: [new webpack.optimize.UglifyJsPlugin()],
}, webpack))
.pipe(gulp.dest('./client/js'));
});

Related

Webpack JS minify

I'm impressed by jscompress.com (ECMAScript 2021 (via babel-minify) and wanted to do the same compression on my Webpack JS file. Tried babel-minify-webpack-plugin and it outputs ERROR in unknown: Unexpected token (115:14).
So without the plugin below is the config I have on webpack.config.js. Without the plugin, compression works. but adding some more codes to the file and the compression is not very good as the jscompress.com.
// webpack.config.js
const path = require('path')
module.exports = {
optimization: {
minimize: true,
},
mode: 'production',
entry: './src/myfile.js',
output: {
filename: 'web.js',
path: path.resolve(__dirname, 'dist')
},
plugins: [],
module: {}
}
// This code added automatically before my code when I don't use the plugin.
!function(e){var r={};function t(o){if(r[o])return r[o].exports;var c=r[o]={i:o,l:!1,exports:{}};return e[o].call(c.exports,c,c.exports,t),c.l=!0,c.exports}t.m=e,t.c=r,t.d=function(e,r,o){t.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:o})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,r){if(1&r&&(e=t(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(t.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var c in e)t.d(o,c,function(r){return e[r]}.bind(null,c));return o},t.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(r,"a",r),r},t.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},t.p="",t(t.s=0)}([function(e,r,t){(function(t){var o,c,n;
// My code is from here onwards
Can anyone help me to compress the JS file correctly?

Webpack 4 exclude entry from output hashing

I've the following webpack 4 configuration for production:
entry: {
app: './src/js/app',
'font-awesome': './src/js/plugins/font-awesome',
'../install/install': './src/js/installation/index',
},
output: {
path: path.join(__dirname, './production/public'),
filename: 'js/[name].[chunkhash].js'
},
I want to exclude install from the output hashing process, but i can't find a way. Is it possible ?
Thanks.
I found a way. It looks like output.filename can be a function. I solded with the following code:
output: {
path: path.join(__dirname, './production/public'),
filename: function(data) {
return data.chunk.name === '../install/install' ? 'js/[name].js' : 'js/[name].[chunkhash].js';
},
chunkFilename: 'js/[name].[chunkhash].js'
},

gulp & webpack: ERROR in Entry module not found

I use webpack for working with JavaScript (ES6 modules bundling, converting to ES5, etc.) and gulp - for other tasks (jade, sass, etc.). I want to keep the webpack configuration in webpack.config.js, but to execute webpack by gulp task.
Project structure
📁 development 
  📁 es6 - source JS
   📄 main.js
  📁 js - output JS for development
   📄 index.js
📁 production
📄 webpack.config.js
📄 gulpfile.js
gulpfile.js
var gulp = require('gulp'),
//...
gulpwebpack = require('gulp-webpack')
gulp.task('gulpwebpack', function(){
return gulp.src('development/03_es6/main.js')
.pipe(gulpwebpack(require('./webpack.config.js')))
.pipe(gulp.dest('development/js/'));
});
// ...
gulp.task('watch', ['browser-sync', 'jade', 'sass'], function() {
// ...
gulp.watch('development/03_es6/*.js', ['test']);
});
gulp.task('default', ['watch']);
webpack.config.js
const NODE_ENV = process.env.NODE_ENV || 'development';
module.exports = {
context: __dirname + '/development',
entry: './03_es6/main.js',
output: {
path: __dirname + '/development/js/',
filename: 'index.js'
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: ['babel-loader']
}
]
}
//watch: NODE_ENV === 'development'
};
Problem
If just to execute webpack from the console (it means to execute the webpack independently from gulp), everything will be correct. However, if to execute gulp gulpwebpack, the error message will appear:
ERROR in Entry module not found: Error: Cannot resolve 'file' or 'directory' ./development/03_es6/main.js in C:\...\projectFrolder/development
I understand that the origin of error is here:
// ...
context: __dirname + '/development',
entry: './03_es6/main.js',
output: {
// ...
However development/03_es6/main.js and ./development/03_es6/main.js will not work too. Gulp can not read webpack.config.js correctly, isn't it?
I think, you should switch to
'use strict';
const gulp = require('gulp'),
named = require('vinyl-named'),
webpack = require('webpack-stream');
gulp.task('webpack', function () {
gulp.src('development/03_es6/main.js')
.pipe(named())
.pipe(webpack(require('./webpack.config.js')))
.pipe(gulp.dest('./build'))
});
Remove entry from webpack.config.js:
module.exports = {
context: __dirname + '/development',
output: {
path: __dirname + '/development/js/',
filename: 'index.js'
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: ['babel-loader']
}
]
}
};

Webpack different names for entries

How i can specify different filename for different entry output?
For example:
module.exports = {
context: path.resolve(__dirname, 'assets'),
entry: {
vendor: ['react', 'react-dom', 'lodash', 'redux'],
app: './src/app.js'
}
output: {
path: path.resolve(__dirname, (isDevelopment) ? 'demo' : 'build'),
filename: (isDevelopment) ? '[name].js' : '[name][chunkhash:12].js'
}
}
To receive output like this
build
-- index.html
-- app.2394035ufas0ue34.js
-- vendor.js
So browser will cache vendor.js with all libraries. Since i don't plan to migrate to any major new release anytime soon and often.
And still being able to break cache for app.js with every update required.
is there some kind of option to set output as
output: {
app: {
...
},
vendor: {
...
},
}
Here is working code:
entry: {
'./build/app': './src/app.js',
'./build/vendor': VENDOR_LIBS // or path to your vendor.js
},
output: {
path: __dirname,
filename: '[name].[chunkhash].js'
},
Add this code into your webpack plugins array as last element of an array.
plugins: [
... // place our new plugin here
]
function() {
this.plugin("done", function(stats) {
const buildDir = __dirname + '/build/';
const fs = require('fs');
var vendorTempFileName = '';
new Promise(function(resolve, reject) {
fs.readdir(buildDir, (err, files) => {
files.forEach(file => {
if (file.substr(0,6) === 'vendor') {
resolve(file);
}
});
});
}).then(function(file) {
fs.rename( buildDir + file, buildDir + 'vendor.js', function(err) {
if ( err ) console.log('ERROR: ' + err);
});
});
});
}
Output should be as follows:
It is considered bad practice to leave your files without chunkhashes, due to browser caching.
For Webpack 4 I added a quick-and-dirty done hook to rename my service worker script:
// Plugin to rename sw-[chunkhash].js back to sw.js
class SwNamePlugin {
apply(compiler) {
compiler.hooks.done.tap("SW Name Plugin", (stats) => {
const swChunk = stats.compilation.chunks.find((c) => c.name === "sw");
fs.rename(path.resolve(outDir, swChunk.files[0]), `${outDir}/sw.js`);
});
}
}
plugins.push(new SwNamePlugin());
This obviates the warning DeprecationWarning: Tapable.plugin is deprecated. Use new API on .hooks instead you'd see following loelsonk's answer.

Output filename for gulp/webpack task

I'm using webpack-stream to integrate webpack into a gulp task, as below:
var gulp = require("gulp");
// var webpack = require('gulp-webpack');
var webpack = require('webpack-stream');
gulp.task("min:webpack",
function () {
return gulp.src('./App/App.js')
.pipe(webpack({
// watch: true,
module: {
entry: './App/App.js',
output: {
filename: 'App.bundle.js'
},
devtool: 'source-map'
}
}))
.pipe(gulp.dest('./App'));
});
Everything seems to be working as expected, except that the output file is always something like 6f7af85206d7f2f6536d.js instead of the expected App.bundle.js. In other similar questions (e.g., How to use gulp webpack-stream to generate a proper named file?), I've read that it was fixed effectively by specifying output: { filename: 'something'} in the configuration, but you can see that I'm doing that.
Any suggestions? Anything I'm overlooking?
OK, dumb mistake on my part. I had the configuration specified incorrectly. This config works as expected:
gulp.task("min:webpack",
function () {
return gulp.src('./App/App.js')
.pipe(webpack({
// watch: true,
entry: './App/App.js',
output: {
filename: 'App.bundle.js'
},
devtool: 'source-map'
}))
.pipe(gulp.dest('./App'));
});

Categories

Resources