Minify HTML after Pug compilation with Laravel Mix - html

Could you help me with the html minification code in one line after laravel-mix-pug?
My code is not working now and I don’t know what is the reason:
let mix = require('laravel-mix');
mix.pug = require('laravel-mix-pug');
let pretty = true;
if (mix.inProduction()) pretty = false;
mix.js(['src/js/main.js', 'src/js/plugins.js'], 'dist/js/scripts.js')
.sass('src/sass/app.scss', 'dist/css/styles.css')
.options({
processCssUrls: false
})
.pug('src/*.pug', '../dist', {
pug: {
pretty: pretty
}
});
mix.webpackConfig({
module: {
rules: [
{
test: /\.html$/,
loader: 'html-loader',
options: {
minimize: {
removeComments: true,
collapseWhitespace: true,
minifyJS: true
},
},
},
],
},
});

Just install html-minifier and edit your package.json with laravel-mix scripts like that:
"minify": "html-minifier --input-dir ./dist --output-dir ./dist --file-ext html --collapse-whitespace --remove-comments --process-conditional-comments --minify-js true",
"prod": "npm run production && npm run minify"

Related

Webpack, babelrc dynamic import not working

I spent quite some time trying to figure this out myself but here I am, with no more options to consider than to reach out to the community for some guidance.
I am trying to do something very simple in principle, dynamically import a component with WebPack, using ES6 modules and babelrc.
I have the following app architecture:
-root
-- root/.webpack.dev.js
-- root/.webpack.prod.js
-- root/.babelrc
-- root/package.json
-- root/node_modules/
-- root/dist/
-- root/src/
--- root/src/index.js
--- root/src/modules/
--- root/src/modules/module1.js
--- root/src/modules/module2.js
--- root/src/modules/module3.js
--- root/src/modules/module4.js
--- root/src/modules/module5.js
In my module1.js (not the real name) I am using the following code to dynamically import module2.js:
async function load(configObject) {
const {
init,
requestPermissions
} = await import( /* webpackChunkName: "chunkname" */ `./module2.js`)
init(configObject)
_namespace.requestPermissions = requestPermissions;
}
My .babelrc file:
{
"presets": [
["#babel/preset-env", {
"targets": "> 0.25%, not dead"
}]
],
"plugins": ["#babel/plugin-syntax-dynamic-import",
["#babel/plugin-transform-runtime",
{
"regenerator": true
}
],
],
"comments": true
}
// "#babel/preset-env"
My Webpack config:
const path = require('path');
const webpack = require('webpack')
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin
const WorkboxPlugin = require('workbox-webpack-plugin');
const {
InjectManifest
} = require('workbox-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
entry: {
lib: "./src/index.js"
},
mode: 'development',
module: {
rules: [{
test: /\.js$/,
use: [{
loader: "babel-loader"
}],
exclude: /node_modules/
}]
},
optimization: {
minimizer: [new TerserPlugin({
test: /\.js(\?.*)?$/i,
parallel: true,
cache: true,
terserOptions: {
ecma: 8,
warnings: false,
parse: {
ecma: 8,
},
compress: {
warnings: false,
comparisons: false,
},
mangle: {
safari10: true,
},
module: false,
output: {
ecma: 5,
comments: false,
ascii_only: true,
},
toplevel: false,
nameCache: null,
ie8: false,
keep_classnames: undefined,
keep_fnames: false,
safari10: false,
},
})],
},
output: {
filename: '[name].js',
chunkFilename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath: "/"
},
devServer: {
contentBase: "dist",
compress: true,
stats: {
colors: true
},
overlay: true
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('development'),
'API_URL': JSON.stringify('ENDPOINT')
}
}),
new BundleAnalyzerPlugin({
generateStatsFile: true
}),
new WorkboxPlugin.GenerateSW({
"swDest": "firebase-messaging-sw.js",
}),
new InjectManifest({
"swSrc": path.join('src', 'firebase-messaging-sw.js')
})
]
};
My package.json:
{
"name": "refactor",
"version": "1.0.0",
"description": "",
"main": "backuprefacto.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "NODE_ENV=production webpack --config=webpack.prod.js",
"build:dev": "webpack --config=webpack.dev.js",
"start": "webpack-dev-server --config=webpack.dev.js"
},
"keywords": [],
"private": true,
"license": "ISC",
"devDependencies": {
"#babel/plugin-syntax-dynamic-import": "^7.2.0",
"#babel/preset-env": "^7.5.5",
"babel-loader": "^8.0.6",
"babel-minify": "^0.5.1",
"babel-minify-webpack-plugin": "^0.3.1",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"terser-webpack-plugin": "^1.4.1",
"uglifyjs-webpack-plugin": "^2.2.0",
"webpack": "^4.39.2",
"webpack-bundle-analyzer": "^3.4.1",
"webpack-cli": "^3.3.7",
"webpack-dev-server": "^3.8.0",
"workbox-webpack-plugin": "^4.3.1"
},
"dependencies": {
"#babel/core": "^7.5.5",
"#babel/plugin-transform-runtime": "^7.5.5",
"#babel/runtime": "^7.5.5",
"firebase": "^6.4.0",
"save": "^2.4.0"
}
}
I have checked all my modules, none of them expect for module1.js are calling module2.js.
I have also explored the option of webpack comments being deleted by babel and therefore added a comments: true to make sure the webpackChunkName is not being deleted but in the end, the only thing that gets built is my lib.js, not the lib.bundle.js that I expect.
I have also tried to remove all the TerserPlugin bit to check if that could have the same impact but nothing changed there.
In the need, what I am looking for is simply to have the module2.js loaded whenever it is invoked, and I therefore expect a new network request to materialise this.
Well, it turns out that if you want to use dynamic imports you need to make sure first that you are not importing at all the module at the top....
In module1.js I was importing twice, once at the top, the "regular way", once the dynamic way which was obviously leading to module2.js being consistently loaded.
I resolve my problem by modify .babelrc, modules: false
["#babel/preset-env", {
"loose": true,
"useBuiltIns": "usage",
"corejs": 3,
"modules": false
}],

how to make auto reload work when HMR enabled

I've been trying multiple times to configure webpack. Everytime I start the process, auto reload works fine all the way, until I enable --hot for web-dev-server, then any change to the html has no impact, no errors, nothing, just a log in terminal that there's been a change, and a log on browser console that there's nothing to update. Hot reload works fine for CSS and JS, and I understand HTML doesn't support HMR but at least expected auto refresh to keep working ...
My configuration below:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlWebpackHarddiskPlugin = require('html-webpack-harddisk-plugin');
const webpack = require('webpack');
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'app.js',
path: path.resolve(__dirname, 'dist'),
},
plugins: [
new HtmlWebpackPlugin({
title: 'Hello world',
template: 'src/views/index.html',
alwaysWriteToDisk: true
}),
new HtmlWebpackHarddiskPlugin(),
new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin()
],
devtool: 'inline-source-map',
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
hot: true,
inline: true,
open: true,
},
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader',
]
}
]
}
};
My scripts in package.json
"scripts": {
"dev": "webpack-dev-server --config webpack.config.js",
"prod": "cross-env NODE_ENV=production webpack -p --config webpack.config.js"
},
I am not sure if this is the "right" way to achieve it. But this is working for me with the following amends.
devServer: {
**contentBase: resolve('src/views'),**
open: true,
hot: true,
stats: "errors-only",
overlay: true,
**watchContentBase: true**
},
This does not seem to make sense to me but, if you set watchContentBase to true and point the contentBase to "dist", you lose HMR and any changes (event to css/js files) will cause a full reload which is not what I was aiming for.
my src structure below:
/ src
- images
- js
- sass
- views
I had also a look at vue-cli which seems to suffer from the same issue. Any changes to the index.html are not reflected (does not trigger a full page reload).

protractor-html-screenshot-reporter does not work

I have done everything as written on https://www.npmjs.com/package/protractor-html-screenshot-reporter, but no HTML or screenshots are saved to folder.
I've installed protractor-html-screenshot-reporter with command:
npm install protractor-html-screenshot-reporter --save-dev
I have then done npm init and saved package.json file, which contains:
...
"devDependencies": {
"jasmine-reporters": "^2.2.0",
"protractor-html-screenshot-reporter": "0.0.21"
},
...
I can also see protractor-html-screenshot-reporter in /node_modules/ folder.
In config file I have the following:
var HtmlReporter = require('protractor-html-screenshot-reporter');
exports.config = {
...
jasmineNodeOpts: {
showColors: true, // Use colors in the command line report.
onComplete: null,
isVerbose: false,
includeStackTrace: false,
defaultTimeoutInterval: 1000000,
print: function() {}
},
onPrepare: function() {
jasmine.getEnv().addReporter(new HtmlReporter({
baseDirectory: '../reports/screenshots',
takeScreenShotsOnlyForFailedSpecs: true,
docTitle: 'Desk test report',
docName: 'desk_report.html',
preserveDirectory: true
}));
}
}
Now when I run protractor conf.js I don't see any /reports/screenshots folder, HTML report or screenshot created. Help please!
Jasmine allure Reporter is better for reports and screenshots
Below is the code for it:
//conf.js
exports.config = {
framework: 'jasmine2',
jasmineNodeOpts: {
showColors: true,
includeStackTrace: true,
defaultTimeoutInterval: 144000000
},
directConnect: true,
seleniumAddress: 'http://localhost:4444/wd/hub',
specs: ['/**/Tests/**/*test.js'],
capabilities: { 'browserName': 'chrome' },
onPrepare: function () {
browser.manage().timeouts().implicitlyWait(15000);
var AllureReporter = require('jasmine-allure-reporter');
jasmine.getEnv().addReporter(new AllureReporter({
allureReport: {
resultsDir: 'allure-results'
}
}));
jasmine.getEnv().afterEach(function (done) {
browser.takeScreenshot().then(function (png) {
allure.createAttachment('Screenshot', function () {
return new Buffer(png, 'base64');
}, 'image/png')();
done();
});
});
}
I Hope this solves your problem. Visit the Link for more information.

How can I configure the webpack or typescript that changes are made immediately?

I've implemented webpack so that it generates one file from my angular application. webpack.js
Now the problem is whenever I change the TypeScript file, I'd have to re-run the webpack to see the effect.
That's slowed the development dramatically.
How can I configure the webpack or typescript that changes are made immediately?
webpack.config.js:
const webpack = require('webpack');
module.exports = {
entry: {
app: './app/main.js',
vendor: './app/vendor.js'
},
output: {
//path: './bin',
filename: 'webpack/webpack-[name].js'
},
resolve: {
extensions: ['', '.js', '.ts']
},
devtool: 'source-map',
module: {
loaders: [
{ test: /\.ts$/, loader: 'ts-loader' },
{ test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ },
{ test: /\.css$/, loaders: ['style', 'css'] },
{ test: /\.json/, loaders: ['json-loader'] },
{ test: /\.html/, loaders: ['raw-loader'] },
{ test: /\.(jpg|png|gif)$/, loaders: ['file-loader'] }
]}
// Add minification
, plugins: [
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
output: {
comments: false
}
})
]
};
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true
}
}
How can I configure the webpack or typescript that changes are made immediately
Actually configure how you run webpack. If you use webpack --watch it automatically updates the bundle as soon as you make a change, but then you still need to refresh the browser page. Even better if you use webpack-dev-server as webpack-dev-server --hot --inline will even reload your browser page immediately.

Configure wallaby for React-redux-es6-typescript-immutable applications

How to configure wallaby for React-redux-es6-typescript-immutable application. I use webstorm editor. My base code is committed here
I tried the following code in wallaby.js, but it throws
ReferenceError: Can't find variable: exports
at src/store.ts:3
module.exports = function (wallaby) {
return {
files: [
'src/*.ts'
],
tests: [
'test/*Spec.ts'
],
compilers: {
'**/*.ts': wallaby.compilers.typeScript({
module: 5, // ES6
target: 2 // ES6
})
},
preprocessors: {
'**/*.js': file => require('babel-core').transform(
file.content,
{sourceMap: true, presets: ['es2015']})
}
}
}
I have more or less the same setup as you. Did you try setting the env variable to node?
My working wallaby.js config file for babel 6 is the following:
module.exports = function() {
return {
files: [
{pattern: "src/**/*.js*"}
],
tests: [
{pattern: "tests/integration/*.js"}
],
env: {
type: "node"
},
preprocessors: {
"**/*.js": file => require("babel-core").transform(file.content, {sourceMap: true, presets: ["es2015"]})
}
};
};