I use webpack to collect and combine all my required JS libraries. I noticed that one of them (Markup.js) is missing from the final minified js file.
After some trial and error I traced the problem to this part of code:
plugins.push(new webpack.optimize.UglifyJsPlugin({
output: {
comments: true, // just for testing
},
compress: {
warnings: false,
},
// skip pre-minified libs
exclude: [/\.min\.js$/gi],
...
If I delete this part, the Markup.js library is part of the final (non-minified) JS file as expected. But when I use the uglify plugin, the Markup.js part is no longer there.
I though this might be because Markup.js is never "used" in the project source code, but using
compress: {
warnings: false,
unused: false,
dead_code: false,
},
makes no difference.
All I want is for the final file to have the same content as before, just minified. The uglify plugin should not make any assumptions about what parts of the code are really "needed".
How can I achieve this?
Related
I have a static page that doesn't need JavaScript. I'm using vue-cli 3 and would like to pass the HTML file through webpack for the purpose of minification. However, this doesn't seem to be possible. Inside vue.config.js, I have this:
module.exports = {
pages: {
static_page: {
template: "./public/static_page.html",
entry: ""
}
}
};
Of course, this fails because entry is required and cannot be empty. Simply placing the file into public will cause vue-cli to copy the file into dist unchanged. This is OK but it's not minified. So how can I tell vue-cli to process a HTML file without JavaScript?
I had to manually invoke the HTML Webpack Plugin. Here's my vue.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
configureWebpack: {
plugins: [
new HtmlWebpackPlugin({
template: "./public/static_page.html",
filename: "static_page.html",
chunks: [],
minify: {
collapseWhitespace: true,
removeComments: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
useShortDoctype: true
}
})
]
}
};
Vue CLI is still copying the file from public to dist unchanged as it would with any other static asset. HTML Webpack Plugin is overwriting this file with the minified version.
Also, setting the minify option to true doesn't seem to do anything. The options have to be listed out explicitly. See Issue #1094.
Another useful link is the list of HTML Webpack Plugin options.
I have worked on a vue project which I created using vue cli. Because of this, eslint is also included in the project. Up until now I haven't done much with eslint. If I understood correctly, eslint helps with stylistic errors, semantic errors etc in the code to identify potential problems.
I only rarely used // eslint-disable-next-line if there was e.g. a console.log clashing with the rules.
Now I wanted to include some new javascript code into the project. This code comes from someone else, so I cloned the repo and then just imported it in my main.js via a relative path to the folder/file that I have cloned. I think this was okay. However now I get some problems with eslint as the imported file has no config for eslint.
This is the exact error originating from the import:
Module build failed (from ./node_modules/eslint-loader/index.js):
Error: No ESLint configuration found
I am not sure what to do now, even though I already searched for the error.
I only saw some config for eslint in the package.json, I think. If it would help to have its content or something else, please say so and I will add it!
How can I tackle this problem? Thanks in advance!
This might be a long shot, but this is the .eslintrc.js file I shove into all my react projects at the root directory to get rid of that error. You'll want to change some of the settings but this is the basic structure.
module.exports = {
parser: 'babel-eslint',
env: {
browser: true,
commonjs: true,
es6: true,
node: true,
jest: true,
},
parserOptions: {
ecmaVersion: 2020,
ecmaFeatures: {
jsx: true,
},
sourceType: 'module',
},
plugins: ['react', 'react-hooks'],
extends: [
'eslint:recommended',
'plugin:react/recommended',
'plugin:react-hooks/recommended',
'plugin:json/recommended',
'prettier',
],
settings: {
react: {
version: 'detect',
},
},
rules: {
'react/prop-types': ['off'],
'react/no-unescaped-entities': ['error', { forbid: ['>', '}'] }],
},
};
I used to have problems with UglifyJS for Webpack and ES6 modules:
ERROR in static/js/vendor.6ccd9e38979a78765c7a.js from UglifyJs
Unexpected token: name (features)
[./node_modules/pica/lib/mathlib.js:19,0][static/js/vendor.6ccd9e38979a78765c7a.js:39003,6]
I read that the new beta version of the Webpack plugin supports ES6:
https://github.com/webpack-contrib/uglifyjs-webpack-plugin
new webpack.optimize.UglifyJsPlugin({
uglifyOptions: {
ie8: false,
ecma: 8, // I also tried 7 and 6
parse: {},
mangle: {
properties: {
// mangle property options
}
},
output: {
comments: false,
beautify: false
},
compress: {},
warnings: true
}
}),
However, now I get another error:
ERROR in static/js/vendor.6ccd9e38979a78765c7a.js from UglifyJs
Unexpected token: name (features)
[static/js/vendor.6ccd9e38979a78765c7a.js:39003,6]
What could be the problem?
You can try installing babel-preset-env and adding presets": [ "env" ] to your webpack.config.js or babelrc.
Uglify cannot parse ES6 on its own( as far as I know), so you need to transpile your code down to ES5, post-processing your generated JS with babel, or use a different minifier. My recommendation is Babelify to which I switched after having constant errors with Uglify.
Edit: The problem might be in your new webpack.optimize.UglifyJsPlugin declaration, There are problems with using this declaration with Webpack 3+. You need to import the uglifyjs-webpack-plugin and change plugin declaration to new UglifyJSPlugin(example). Here is a reference.
Example:
const UglifyJSPlugin = require('uglifyjs-webpack-plugin')
const config = {
...
plugins: [
new UglifyJSPlugin({ uglifyOptions: { ...options } })
]
}
For anyone arriving here stuck for various reasons on webpack3 and webpack.optimize.UglifyJsPlugin:
For us, the answer was to let our webpack babel-loader transpile those node_modules. Instead of sending all node_modules through the babel loader (which isn't recommended for performance reasons), you can exclude all apart from specific packages and package name patterns like this:
exclude: /node_modules\/(?!(react-markdown|mdast-util-.*|micromark-.*)\/).*/
I'm running some Karma tests using Intellij and one of them is failing. The stacktrace I get from the output seems to be giving me the lines in the Javascript and not the CoffeeScript, making it much harder for me to debug. Is there any way I can get the stacktrace lines to show up in their proper Coffeescript format?
1. Preprocessor Configuration
Make sure you have your preprocessor settings enabled in karma.conf.js.
preprocessors: {
'**/*.coffee': ['coffee']
},
coffeePreprocessor: {
options: {
bare: true,
sourceMap: true
},
transformPath: function(path) {
return path.replace(/\.js$/, '.coffee');
}
}
If your karma.conf is also in coffeescript (i.e. karma.conf.coffee), it would look like this:
preprocessors: '**/*.coffee': ['coffee']
coffeePreprocessor:
options:
bare: true
sourceMap: true
transformPath: (path) ->
path.replace /\.js$/, '.coffee'
2. Use Karma's Default Browser
Make sure you're using "Chrome" as your Karma browser (not PhantomJS). This is also specified in your karma config.
While PhantomJS does allow for mapping JS line numbers to Coffeescript line numbers, it doesn't do so properly at this time.
browsers: ['Chrome']
If I use RequireJS to optimize my whole project my main module will not get optimized/uglified if I use the setting skipDirOptimize: true. From my understanding everything should be optimized except the non-build layer JS files. Is this a bug or me not understanding the correct usage of this parameter?
Here is my requirejs config:
{
appDir: '../project',
mainConfigFile: '../project/assets/js/main.js',
dir: '../httpdocs',
optimize: "uglify",
//Introduced in 2.1.2: If using "dir" for an output directory, normally the
//optimize setting is used to optimize the build layers (the "modules"
//section of the config) and any other JS file in the directory. However, if
//the non-build layer JS files will not be loaded after a build, you can
//skip the optimization of those files, to speed up builds. Set this value
//to true if you want to skip optimizing those other non-build layer JS
//files.
skipDirOptimize: true,
generateSourceMaps: false,
normalizeDirDefines: "skip",
uglify: {
toplevel: true,
ascii_only: true,
beautify: false,
max_line_length: 1000,
defines: {
DEBUG: ['name', 'false']
},
no_mangle: false
},
optimizeCss: "standard",
removeCombined: true,
modules: [
{
name: '../main'
}
]
}
The use of the relative path in your module is probably causing r.js to not recognise it as a build bundle at the point where it decides whether or not to optimize it.
I had a similar problem (build bundles not being optimized), not with a relative module path but with a paths config to allow my modules to be named differently to my folder structure:
({
...
skipDirOptimize: true,
paths: {
'MyLibrary': ''
},
modules: [
{ name: 'MyLibrary/Main' }
],
...
})
This causes the module name in r.js (2.1.8) to become /Main, so when it builds its _buildPathToModuleIndex mapping, the key will be incorrect due to having two slashes (e.g. C:\dev\project\output\\Main).
The way that the optimization loop decides if a module is a build bundle (and hence needs optimization even when skipDirOptimize: true) is by looking it up in the _buildPathToModuleIndex mapping using its filename (e.g. C:\dev\project\output\Main). Due to it being in the map with two slashes, it won't find it. Therefore it won't be considered to be a build bundle and won't be optimized.
Try putting some console.logs in r.js where it builds and accesses _buildPathToModuleIndex to see what it's putting in and what it uses to look it up.
For my problem, the solution was to add a paths entry for 'MyLibrary/Main': 'Main' (repetition unfortunately). I'm not sure what your project structure is, but how about if you set baseUrl: '../ and then simply call your module main ?