How to uglify javascript using webpack - javascript

Here is my webpack config:
var path = require('path');
var webpack = require('webpack');
var CompressionPlugin = require("compression-webpack-plugin");
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
entry: './index.js',
output: {
path: __dirname,
filename: 'public_html/assets/js/bundle.js'
},
resolveLoader: {
modules: ["node_modules"]
},
module: {
rules: [
{
enforce: 'pre',
test: /\.tag$/,
exclude: /node_modules/,
loader: 'riotjs-loader',
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
options: {
presets: [
'es2015',
],
"babelrc": false
}
},
{
test: /\.css$/,
use: [
{
loader: "css-loader",
options: {
modules: false
}
}
]
}
]
},
plugins: [
new webpack.LoaderOptionsPlugin({debug: true}),
new UglifyJSPlugin(),
new webpack.ProvidePlugin({
riot: 'riot'
}),
new CompressionPlugin({
asset: "[path].gz[query]",
algorithm: "gzip",
test: /\.(js|html)$/,
threshold: 10240,
minRatio: 0.8
})
]
}
This completely uglifies the bundle js but the problem is global variables references are lost. I mean the properties of global object DataMixin are lost.
For example, inside index.html I have:
<script>
window.onload = function () {
DataMixin.get_data_page_load(); //DataMixin defined in other js file
};
</script>
After uglifying, I get error:
Cannot read property 'get_data_page_load' of undefined
How do I fix this? I am using webpack 2.

For webpack 2 you don't need to install the external uglify plugin.
In your webpack config replace this new UglifyJSPlugin(), with the following:
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
minimize: true,
compressor: {
warnings: false,
},
}),

Removing presets fixed it but also had to remove arrow functions from my code.
Here is the solution I found: http://www.rootscopeblog.com/blog/post?=uglifying-riotjs-files-using-webpack-2

Related

SCSS sourcemaps not working with Webpack 3 + ExtractTextPlugin

I'm trying to enable sourcemaps for my SCSS in my app and have a really puzzling situation on my hands. Here's my config file:
const webpack = require('webpack');
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCSSAssets = require('optimize-css-assets-webpack-plugin');
let config = {
entry: './src/index.ts',
devtool: 'eval-source-map', // for choosing a style of source map
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, './dist')
},
devServer: {
contentBase: path.resolve(__dirname, './dist'), // A directory or URL to serve HTML content from
historyApiFallback: true, // fallback to /index.html for SPA
inline: true,
open: false // open default browser on launch
},
module: {
rules: [
{
test: /\.ts$/, // files ending with .ts
exclude: /node_modules/, // exclude the node modules directory
use: 'ts-loader'
},
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["env"]
}
}
},
{
test: /\.scss$/, // files ending with .scss
use: ['css-hot-loader'].concat(
ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
// { loader: 'style-loader', options: { sourceMap: true } },
{ loader: 'css-loader', options: { sourceMap: true } },
{ loader: 'postcss-loader', options: { sourceMap: true } },
{ loader: 'sass-loader', options: { sourceMap: true } },
],
})
)
},
{
test: /\.(png|svg|jpg|gif)$/, // for other file types
use: ['file-loader?name=[name].[ext]&outputPath=img/']
}
]
},
resolve: {
extensions: ['.ts', '.js']
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
}),
new ExtractTextPlugin('styles.css') // call the ExtractTextPlugin and name our CSS file
]
};
module.exports = config;
if (process.env.NODE_ENV === 'production') {
module.exports.plugins.push(
new webpack.optimize.UglifyJsPlugin(), // call the uglify plugin
new OptimizeCSSAssets() // call the CSS optimizer (for minification)
);
}
What's really strange is that here, everything in the terminal compiles fine but when I inspect an element, there's no sourcemap:
HOWEVER, if uncomment this line in my webpack.config file:
// { loader: 'style-loader', options: { sourceMap: true } },
and run npm start again, the sourcemaps work correctly!...
...but now the terminal throws an error, which apparently is because you aren't supposed to use style-loader inside of the ExtractTextPlugin, but rather only as a fallback. My app still works in this case, but I don't want that error! How can I enable the SCSS sourcemaps without including style-loader in my SCSS rules?

webpack does not output css

Situation
I have a webpack setup, where I have a rule that extracts CSS and/or SASS from .ts files using the extract-text-webpack-plugin and sass-loader.
I import my SCSS file in a seperate .ts file
import './scss/style.scss'
Problem
A CSS file is expected to be in the output folder ( dist ).
The compilation completes without an error, yet there is no CSS file in the build folder.
Here is my webpack configuration:
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var styleString = require('css-to-string-loader');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
const extractSass = new ExtractTextPlugin({
filename: "[name].css",
disable: process.env.NODE_ENV === "development"
});
var helpers = require('./helpers');
var isProd = process.env.NODE_ENV === 'production';
module.exports = {
entry: {
polyfills: './src/polyfills.ts',
vendor: './src/vendor.ts',
app: isProd ? './src/main.aot.ts' : './src/main.ts'
},
resolve: {
extensions: ['.ts', '.js']
},
module: {
rules: [{
test: /\.ts$/,
loaders: [
'babel-loader',
{
loader: 'awesome-typescript-loader',
options: {
configFileName: isProd ?
helpers.root('tsconfig-aot.json') :
helpers.root('tsconfig.json')
}
},
'angular2-template-loader'
],
exclude: [/node_modules/]
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015']
}
},
{
test: /\.html$/,
loader: 'html-loader'
},
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
loader: 'file-loader?name=assets/[name].[ext]'
},
{
test: /\.(json)$/,
loader: 'file-loader?name=assets/mocks/[name].[ext]'
},
{
test: /\.(css|scss)$/,
loaders: ['to-string-loader', 'css-loader', 'sass-loader']
}
]
},
plugins: [
// Workaround for angular/angular#11580
new webpack.ContextReplacementPlugin(
// The (\\|\/) piece accounts for path separators in *nix and Windows
/angular(\\|\/)core(\\|\/)#angular/,
helpers.root('./src'), // location of your src
{} // a map of your routes
),
new webpack.optimize.CommonsChunkPlugin({
name: ['app', 'vendor', 'polyfills']
}),
new HtmlWebpackPlugin({
template: 'src/index.html'
})
]
};
Reason
The reason there is not output CSS file is because you are not using the
const extractSass = new ExtractTextPlugin({
filename: "[name].css",
disable: process.env.NODE_ENV === "development"
});
in your CSS|SCSS rule
{
test: /\.(css|scss)$/,
loaders: ['to-string-loader', 'css-loader', 'sass-loader']
}
Solution
You have to make use of the use property like so:
{
test: /\.(css|scss)$/,
use: extractSass.extract({ // <==== Right here, note the "extractSass"
use: [
{ loader: "to-string-loader" },
{ loader: "css-loader" },
{ loader: "sass-loader" }
],
fallback: "style-loader"
})
}
And add to your plugins array the ExtractTextPlugin instance ( extractSass ):
plugins: [
extractSass
]
You might also want to take a look here.

Module not found: Error: Cannot resolve module 'module'

I want to load module from variable string
var abc = './../containers/BlankContainer';
require(abc);
but it cannot find module, so I install 'require-from-string' module from npm.
Now when I build it's giving error
ERROR in ./~/require-from-string/index.js
Module not found: Error: Cannot resolve module 'module' in D:\Nilay\RnD\node_modules\require-from-string
# ./~/require-from-string/index.js 3:13-30
I found it is webpack issue, here is my webpack config:
const webpack = require('webpack');
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin')
var entry = [path.resolve(__dirname, 'app/bootstrap.js')];
var output = {
path: path.resolve(__dirname, 'public/dist'),
filename: 'bundle-[name].js',
publicPath: "dist/"
};
var modules = {
loaders: [
{ test: /\.json$/, loader: "json-loader" },
{ test: /\.js$/,
loader: ['babel-loader'], exclude: /node_modules/, query: { cacheDirectory: 'babel_cache', presets: ['react', 'es2015'] } },
{ test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader!autoprefixer-loader") },
{ test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader" },
{ test: /\.(woff|woff2)$/, loader: "file-loader" },
{ test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader" },
{ test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader" }
]
};
var plugins = [
new ExtractTextPlugin("bundle.css"),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
}),
new webpack.ProvidePlugin({
jQuery: 'jquery',
$: 'jquery',
jquery: 'jquery'
}),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin({ // minimize/compress all js chunks
compress: { warnings: false },
mangle: false,
sourcemap: false,
beautify: false,
dead_code: true
})
]
module.exports = {
entry: entry,
output: output,
stats: { colors: true },
watch: true,
module: modules,
plugins: plugins,
resolveLoader: {
root: path.join(__dirname, 'node_modules')
},
resolve: {
modules: [path.resolve(__dirname, '/app/routes'), 'node_modules/'],
descriptionFiles: ['package.json'],
extensions: ['', '.js', '.ts']
}
};
How can I resolve it?

webpack jquery plugin perfect-tooltip

I'm trying to load the perfect-tooltip jquery plugin (http://tborychowski.github.io/perfecttooltip/) using webpack.
I successfully loaded other jquery plugins like: typed.js and backstretch by following the instructions provided here (Managing jQuery plugin dependency in webpack) but they don't seem to work with that specific plugin.
When I run the bundle an error tells me that the tooltip function (exported by the plugin) is not defined. It seems the plugin is not loaded by jquery. I thought the plugin tried to load its own instance of jquery so I used an alias:
alias: {
'jquery': require('jquery'),
}
It didn't solve the problem.
My current webpack configuration:
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var CleanWebpackPlugin = require('clean-webpack-plugin');
var CopyWebpackPlugin = require('copy-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var moment = require('moment');
var path = require('path');
var environment = process.env.APP_ENVIRONMENT || 'dev';
module.exports = {
entry: {
'app': './src/main.ts',
'polyfills': './src/polyfills.ts',
'vendor': './src/vendor.ts'
},
devtool: 'source-map',
output: {
path: './dist',
filename: '[name].browser.' + moment().format('DDMMYYYYHHmm') + '.js'
},
module: {
loaders: [
{ test: /\.component.ts$/, loader: 'ts!angular2-template' },
{ test: /\.ts$/, exclude: /\.component.ts$/, loader: 'ts' },
{ test: /\.html$/, loader: 'raw-loader' },
{ test: /\.css$/, include: path.resolve('src/app'), loader: 'raw-loader' },
{
test: /\.css$/, exclude: path.resolve('src/app'), loader: ExtractTextPlugin.extract('style', 'css', {
fallbackLoader: "style-loader",
loader: "css-loader"
})
},
{ test: /\.(png|jpe?g|gif|ico)$/, loader: 'file?name=fonts/[name].[ext]' },
{ test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/font-woff&name=fonts/[name].[ext]" },
{ test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/font-woff&name=fonts/[name].[ext]" },
{ test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/octet-stream&name=fonts/[name].[ext]" },
{ test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: "file?name=fonts/[name].[ext]" },
{ test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=image/svg+xml&name=fonts/[name].[ext]" },
]
},
resolve: {
extensions: ['', '.js', '.ts', '.html', '.css']
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: ['vendor', 'polyfills']
}),
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new webpack.DefinePlugin({
app: {
environment: JSON.stringify(environment),
config: JSON.stringify(require('./profile/' + environment + ".profile.js"))
}
}),
new CleanWebpackPlugin(
['dist']
),
new CopyWebpackPlugin([
{ from: './src/images', to: 'images' }
]),
new ExtractTextPlugin('[name].browser.css'),
new webpack.optimize.UglifyJsPlugin({ minimize: true }),
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery"
})
]
};
Any insight?
Eventually I managed to load that script.
The package.json file provided in the package doesn't have a main property, Webpack was simply trying to bundle all files in the package.
I solved that by requiring two specific files: "js/jquery.tooltip.js" and "css/tooltip.css".

Webpack relative path resolve error

I'm importing a module like this import { validate } from '../../_lib';
but webpack throws me an error ModuleNotFoundError. Looking inside it seems like it parses the path in a wrong why: resolve file c:/Users/Me/project/resource/func\\_lib doesn't exist
My directory looks something like this:
project
resource
func
file.js
_lib
validate.js
index.js
in validate.js I'm exporting a func like this export function validate(){}
and in index.js I'm exporting validate this way export * from './validate'
this is mt webpack config
var webpack = require('webpack');
module.exports = {
// entry: provided by serverless
// output: provided by serverless
target: 'node',
externals: [
'aws-sdk',
'dynamodb-doc'
],
resolve: {
extensions: ['', '.js', '.jsx']
},
devtool: 'source-map',
plugins: [
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin({
compress: {
unused: true,
dead_code: true,
warnings: false,
drop_debugger: true
}
}),
function () {
this.plugin("done", function (stats) {
if (stats.compilation.errors && stats.compilation.errors.length) {
console.error(stats.compilation.errors)
throw new Error(stats.compilation.errors);
}
});
}
],
module: {
loaders: [
{
test: /\.json$/,
loader: 'json'
},
{
test: /\.html$/,
loader: 'html'
},
{
test: /\.js$/,
loader: 'babel',
exclude: /node_modules/,
query: {
presets: ['es2015', 'stage-0']
}
}
]
}
};

Categories