Webpack JS minify - javascript

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?

Related

webpack module function not found

I have a simple project with a few html files in root folder and a few javascript modules in scripts directory.
I want to start using webpack now because I want minification and to start using environments. Everything was working before I started using webpack.
I read documentation for Webpack 5 but could not find anything that solves my problem. So I came up with this webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require("html-webpack-plugin")
module.exports = {
entry: {
lib: "./scripts/lib.js"
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
},
devServer: {
contentBase: "./dist",
inline: true, //Enable watch and live reload
host: "localhost",
port: 8080,
stats: "errors-only",
https: false
},
plugins: [
new HtmlWebpackPlugin({
filename: "index.html",
template: "index.html",
hash: true
})
],
module: {
rules: [
{
test: /\.html$/i,
loader: 'html-loader',
},
],
},
};
My index.html imports and uses module functions like this:
<script type="module">
import * as lib from "./scripts/lib.js";
window.lib = lib;
</script>
<body onload="lib.myFn()">
</body>
But after running this webpack (using webpack serve) I am getting "is not a function" or "module not found" errors.
How can I compile and run my existing project with webpack without making any changes in my directory structure and fix this error so I can start using functions in lib.js in my index.html? Thanks.

Functions are not available in webpack bundle

I'm working on Arrow project and I'm in phase to create the Bundle file using Webpack.
I grouped my modules in a folder. and for each folder I have index.js where I export all modules.
Also, I have global index.js that imports all index.js like this :
import * as Has from "./scripts/array/has"
import * as Math from "./scripts/array/math"
import * as Arrow from "./scripts/array"
export { Has, Math, Arrow }
Now, I want to create my bundle from this global index.js .
My Webpack configuration looks like :
const path = require("path")
const { CleanWebpackPlugin } = require("clean-webpack-plugin")
module.exports = {
mode: "development",
entry: {
arrow: "./src/1.x.x/index",
},
plugins: [
new CleanWebpackPlugin({ cleanStaleWebpackAssets: false }),
],
devtool: 'inline-source-map',
devServer: {
contentBase: './build',
},
output: {
filename: "[name]-alpha.js",
path: path.resolve(__dirname, 'build'),
},
optimization: {
splitChunks: {
chunks: 'all',
},
},
}
The Issue is when I try to import my functions from the build the functions do not appear in the Autocomplete and I received errors that these functions are undefined!
I have just ___esModule :
import { __esModule } from "./arrow-alpha"
I want to let developers use and import the functions like the example
import {omit} from "arrow" // arrow is the bundled file
const frameworks = ["react", "vue", "ember", "angular"];
const withoutAngular = omit(frameworks,"angular");
console.log(withoutAngular); // ["react", "vue", "ember"]
I blocked in this step for days and I could not figure out the issue.
It sounds like you are looking to export your code as library with webpack. In order to do so, you should export your library module as umd which can work for backend/client side so IDE can also understand what you export. Just add following configuration in your webpack.config.js:
output: {
libraryTarget: 'umd', // style for your library
library: 'yourLibName', // if you keen to have a name for library
// ...
},
NOTE: this only works if you pass to webpack a cjs style code, otherwise it will convert to harmony module which you can't export accordingly (such as esm module)
In order to make sure babel would convert your esm module to commonjs, you have to set modules to commonjs like this:
babel.config.js or .babelrc
[
"#babel/preset-env",
{
"modules": "commonjs",
}
]
Adding below Configuration. Will eject your final bundle to be accessed as Window.Arrow on adding script to index.html page
output: {
filename: "[name]-alpha.js",
path: path.resolve(__dirname, 'build'),
library: 'Arrow',
libraryTarget: 'var'
},
and your index.js page inside src folder to be as
module.exports = require('./scripts/array');

Webpack: vendor bundle not imported in main output

I'm struggling with what looks like a generic error from Webpack after trying to optimise my source code.
Assuming I have the following files in ./src:
├── main.js
├── moduleA.js
└── moduleB.js
main.js imports and uses ModuleA.
moduleA.js imports and uses ModuleB
ModuleA.js and ModuleB.js both import flatten-array from node_modules
My expectation is that if I try to optimise my bundle (see below) it will output two files:
1. index.js
2. vendors~main.index.js
Trying to execute the index.js output bundle results in:
/******/ modules[moduleId].call(module.exports, module,
module.exports, __webpack_require__);
^
TypeError: Cannot read property 'call' of undefined
Although the files are generated, index.js doesn't appear to import vendors~main.index.js. Yet it executes fine when removing the optimization (and vendors javascript)
Is this the correct assumption? How can I make it work like this?
While this is a bundle for Node, there are valid reasons that I'd like to export a vendors file.
Accompanying git repo to reproduce available here:
https://github.com/supasympa/webpack-vendors-issue
Files are:
main.js
const moduleA = require('./moduleA');
moduleA.log('log from main.js');
moduleA.js
const moduleB = require('./moduleB');
const flatten = require('array-flatten');
module.exports.log = function(msg){
moduleB.log('logging from moduleA.js');
console.log(`ModuleA logging: ${msg}`);
console.log(`flattened: ${flatten([[1,2,3],[4,5],[6,7]])}`)
};
moduleB.js
const flatten = require('array-flatten');
module.exports.log = function(msg){
console.log(`ModuleB logging: ${msg}`);
console.log(`flattened: ${flatten([[1,2,3],[4,5],[6,7]])}`)
};
webpack.config.js
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
module: {
rules: [{
include: [path.resolve(__dirname, 'src')],
loader: 'babel-loader',
options: {
plugins: ['syntax-dynamic-import'],
presets: [['env', {
'modules': 'commonjs'
}]]
},
test: /\.js$/
}]
},
entry: './src/main',
target: 'node',
output: {
filename: 'index.js',
path: path.resolve(__dirname, 'dist')
},
mode: 'development',
optimization: {
splitChunks: {
cacheGroups: {
vendors: {
priority: -10,
test: /[\\/]node_modules[\\/]/,
enforce: true
},
},
// concatenateModules: false,
chunks: 'all',
minChunks: 1,
minSize: 0,
name: true
}
},
plugins: [
new CleanWebpackPlugin(['dist']),
]
};
It turns out that this is not yet implemented outside of the browser, in Webpack.
https://github.com/webpack/webpack/issues/8330
https://github.com/webpack/webpack/issues/8161
https://github.com/webpack/webpack/issues/8156
Defining, chunks: 'all', you're explicitly taking all initial entries and async imports (by default it only on-demand async chunks) and specifying the bundler to create a new vendor chunk/file out of that.
So the behavior is as expected. The idea is to remove the common dependencies from entry files so they can be shared and the page has to load less vendors/common code overall.
One way to explicitly control what the entry files include is this pattern: https://github.com/webpack/webpack/tree/master/examples/two-explicit-vendor-chunks

Django + Webpack + Vue + Code splitting - How to change load url of chunk files

I am using Django with Webpack and Vue, And Code splitting in Webpack. Webpack split chunk files from source code of .vue files. But, I can't load chunk files on Web browser because url is incorrect in my project structure. I want to change load url of chunk files but I don't know these. How to change load url of chunk files?
Chrome console logs:
GET http://localhost:8123/mycomponent.chunk.js 404 (Not Found)
main.js:12 Error: Loading chunk 2 failed.
(error: http://localhost:8123/mycomponent.chunk.js)
at HTMLScriptElement.a (main.js:1)
I need url of '/static/js/mycomponent.chunk.js'.
webpack.config.js:
const path = require("path")
const webpack = require('webpack')
const BundleTracker = require('webpack-bundle-tracker')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
context: __dirname,
entry: './src/main.js',
output: {
path: path.resolve('../static/js/'),
filename: "[name].js",
chunkFilename: '[name].chunk.js',
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader'
},
],
},
plugins: [
new BundleTracker({filename: './webpack-stats.json'}),
new VueLoaderPlugin(),
],
resolve: {
alias: {
'vue': path.resolve('./node_modules/vue/dist/vue.js'),
}
},
}
Try adding publicPath: '/static/js/' to output.
Also, if you serve your js from your Django template page, you can use django-webpack-loader, it simplifies serving js files and supports hot module reloading.

Redundant Modules in Webpack Dllplugin

I am using Webpack 3.0.0 for my application. I am trying to split my references to libraries in to separate files using the DllPlugins in Webpack. Initially I was using CommonsChunkPlugin which allowed me to split my libraries as jquery.js and kendo.js . The kendo.js file did not contain the jquery library.
After I changed this using DllPlugin, it seems both jquery.js and kendo.js have jquery.
Below is my configuration
var webpack = require('webpack');
var path = require('path');
module.exports = {
entry: {
jquery: ["jquery"],
kendo: [
'kendo.autocomplete.min',
'kendo.treelist.min',
'kendo.slider.min',
'kendo.tooltip.min',
'kendo.dataviz.chart.min',
'kendo.dataviz.themes.min',
'kendo.grid.min',
'kendo.data.min',
'kendo.core.min'
]
},
output: {
filename: "[name].bundle.js",
path: path.resolve(__dirname, '../assets'),
library: "[name]_lib"
},
plugins: [
new webpack.DllPlugin({
path: path.resolve(__dirname, '../assets/[name]-manifest.json'),
name: '[name]_lib'
})
],
};
Could someone please help change the configuration to exclude jquery from kendo.js .

Categories

Resources