How to stop Webpack-3's PurifyCSSPlugin from cleaning to much? - html

Problem
Everything else equal, my final pages differ in their CSS result. The prod version lacks the proper flexbox alignment as seen in the following comparison:
Dev
Prod
The problem is caused by the PurifyCSSPlugin. I don't know how to configure it still cleaning up the right parts of the css, keeping the parts I really need?
Any help would be appreciated. The complete code is available here.
Research so far
Update 2017-08-21:
In the production version there is css missing for the following classes
subtitle
title:not(.is-spaced) + .subtitle {
margin-top: -1.5rem;
}
columns
#media screen and (min-width: 769px), print
.columns:not(.is-desktop) {
display: flex;
}
Setup
I use webpack-3 together with bulma to make a webpage. I have two script tasks defined to build my application 1. in development and 2. for production.
"dev": "webpack-dev-server --progress --colors",
"prod": "npm run clean && NODE_ENV=prod webpack -p",
Inside my webpack config I switch between two configurations for the css handling, depending on the NODE_ENV variable. The config looks as follows:
const cssConfigEnvironments = {
'dev': ['style-loader', 'css-loader?sourceMap', 'sass-loader'],
'prod': ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader', 'sass-loader']
})
}
In addition I disable the ExtractTextPlugin for development.
new ExtractTextPlugin({ // Builds .css, see https://github.com/webpack-contrib/extract-text-webpack-plugin
filename: '[name].css',
allChunks: true,
disable: !envIsProd
}),
The only noticeable info shown inside the console is the following deprecation warning:
(node:2275) DeprecationWarning: Chunk.modules is deprecated. Use Chunk.getNumberOfModules/mapModules/forEachModule/containsModule instead.

The problem is really coming from the PurifyCSSPlugin there is an issue already open tackling it.
As a quick fix you have to whitelist the not tag:
new PurifyCSSPlugin({
// Give paths to parse for rules. These should be absolute!
paths: glob.sync(path.join(__dirname, 'src/*.html')),
minimize: envIsProd,
purifyOptions: {
info: true,
whitelist: [ '*:not*' ]
}
})

Related

compiling Promises with babel and core-js causes infinite window reload

I want to run the following piece of code on IE11
let myPromise = Promise.resolve(123);
myPromise.then((value) => {
console.log(value);
});
My recipe is Rollup and babel (& core-js for polyfilling) with the following .babelrc configuration:
{
"presets": [
["#babel/preset-env", {
"useBuiltIns": "usage",
"corejs": 3,
"targets": {
"browsers": ["last 2 versions", "ie >= 11"]
}
}]
]
}
When I try to load the code, I get some infinite loop. The browser's tab seems to reload every couple of milliseconds.
I just wanted you to know that your question/issue in core-js (https://github.com/zloirock/core-js/issues/627) was really helpful and solved the problem for me, which was exactly the same as yours there and here.
So I wanted to leave here the solution provided there by Denis Pushkarev - as I did find this topic first and it may help other developers to quick get an answer:
You could change options to format: 'iife' to make it work.

How can I check to see if a task is ran as a dependency of another task in gulp#4?

I use gulp-notify to trigger notifications when tasks complete. If a task is ran standalone, a notification for that specific task is triggered. If a task is ran as a dependency of another task, a notification for all dependencies is triggered.
In gulp#3, I check if the task is being called as a dependency using gulp.seq, which contains an array of the tasks being ran. Let's say I have three tasks: default, styles, and scripts, with the later two set as dependencies of the first. When running gulp styles, gulp.seq will contain [ 'styles' ]. When running gulp (the default task), gulp.seq will contain [ 'styles', 'scripts', 'default' ]. Knowing that, I then check gulp.seq.indexOf("styles") > gulp.seq.indexOf("default"), which tells me weather or not styles was ran as part of the default task.
With gulp#4, it appears that gulp.seq no longer exists. I've tried digging through the documentation and source code with no luck. It seems like gulp.tree({ deep:true }) (docs) might be what I'm looking for, but I don't see anything in it that returns anything useful.
Is there an equivalent of gulp.seq in gulp#4?
The API gulp.seq was never an official prop exposed by Gulp. With Gulp 4, you cannot do that. gulp.tree({ /* */ }) will not solve this problem for you.
Having said that, if you still need to find whether a task has run during some other task's pipeline, then you will have to decorate every gulp task with your own wrapper using something like this:
let runTasks = [];
function taskWrapper(taskName, tasks, thisTask) {
let callbackTask;
function innerCallback(cb) {
runTasks.push(taskName);
cb();
}
if (thisTask) {
callbackTask = function(cb) {
thisTask(function () {
innerCallback(cb);
});
}
} else {
callbackTask = innerCallback;
}
const newTasks = [ ...tasks, callbackTask ];
gulp.task(taskName, gulp.series(newTasks));
}
// INSTEAD OF THIS
// gulp.task('default', gulp.series('style', 'script', function () { }));
// DO THIS
taskWrapper('default', ['style', 'script'], function(cb) {
console.log('default task starting');
cb();
});
NOTE: Above code snippets has limitation. If you use watch mode, array maintaining the executed tasks i.e. runTasks will keep on growing. Also, it assumes tasks will always run in series. For a parallel mode, the logic gets little complicated.
Finally, you can also have a predefault task to help it further:
taskWrapper('predefault', [], function(cb) {
// RESET runTasks
runTasks = [];
cb();
});
taskWrapper('default', ['predefault', 'style', 'script'], function(cb) {
console.log('default task starting');
cb();
});
Also, I am doubtful if gulp-notify will work with Gulp 4.
Through a bit of luck, I discovered this was possible via the module yargs, which I already have installed.
When running gulp styles, for example, I can check argv._.indexOf("styles") > -1, as it contains ['styles']. When running gulp (i.e the default task), it contains []. In my testing, this works perfectly for my use case.

Chrome args and prefs don't seems to be work in protractor conf

Need help with below issues. I have work around for issue 1 so any tips on issue 2 would be great:
--start-maximized won't trigger full window so my current work around is adding below line in beforeEach function:
browser.driver.manage().window().maximize();
Trying to download file to default directory but the file is just going to download folder on my C drive instead of /tmp/downloads (on another drive).
My config:
capabilities: {
'browserName': 'chrome',
'chromeOption': {
args: ['--lang=en', '--start-maximized'],
prefs: {
'download': {
'prompt_for_download': false,
'default_directory': '/tmp/downloads',
},
},
},
},
As for download, I'm currently using solution from here.
There is a typo. It should be chromeOptions, not chromeOption.
I think the options in protractor conf have been updated to be without "--".
So perhaps try without "--"?
args: ['lang=en', 'start-maximized']

-sass-debug-info at my css

I'm working on a code with css and I found every class wrote before it
#media -sass-debug-info{filename{font-family:file\:\/\/C\:\/www\/w-balls-html\/html_source\/lib\/_master\.scss}line{font-family:\00003640}}
I found the at the doc of saas something about it
- ({#to_s => #to_s}) debug_info
A hash that will be associated with this rule in the CSS document if the :debug_info option is enabled. This data is used by e.g. the FireSass Firebug extension.
Returns:({#to_s => #to_s}) [debug-info-documentation][1]
but couldn't know how to debug it or know how to convert to the normal #media
#media all and (max-width: 699px) and (min-width: 520px))
If you are using Grunt to run your application, you can edit the Gruntfile.js file. You are looking for the Compass section. I found it around line 175. In that section you want to modify the the Server debugInfo to false.
// Compiles Sass to CSS and generates necessary files if requested
compass: {
options: {
sassDir: '<%= yeoman.app %>/styles',
cssDir: '.tmp/styles',
generatedImagesDir: '.tmp/images/generated',
imagesDir: '<%= yeoman.app %>/images',
javascriptsDir: '<%= yeoman.app %>/scripts',
fontsDir: '<%= yeoman.app %>/styles/fonts',
importPath: './bower_components',
httpImagesPath: '/images',
httpGeneratedImagesPath: '/images/generated',
httpFontsPath: '/styles/fonts',
relativeAssets: false,
assetCacheBuster: false,
raw: 'Sass::Script::Number.precision = 10\n'
},
dist: {
options: {
generatedImagesDir: '<%= yeoman.dist %>/images/generated'
}
},
server: {
options: {
debugInfo: false
}
}
},
By changing the option to false you will not have the debug info in the file. I recommend that you leave the debug info while in development. When the site is finished and ready for production THEN remove the debug info.
Lastly, this will not remove the comments out of the CSS file. You may notice that Compass inserts a location comment at the beginning of each selector. (See below)
/* line 19, ../../bower_components/bootstrap-sass-official/assets/stylesheets/bootstrap/_normalize.scss */
body { margin: 0; }
In order to remove that you will need to use Minification. Grunt can also take care of that. You will need to make sure the Gruntfile.js is configured. (I found mine to be commented out with // before every line. I had to remove those lines) After that just run
grunt cssmin
These 2 steps took a 475 KB CSS file down to 110 KB.
Hope this helps!
I was trying to figure out how to use that information myself to edit the original SASS files and learned that it is used for developing using a FireSASS plugin.
If you want human readable debug line number you want the noLineComments grunt setting, like so:
debug: {
options: {
watch: false,
outputStyle: 'expanded',
debugInfo: false, // this generates browser debug info, not human friendly
noLineComments: false, // human friendly debug comments
}
},
Which will spit out something like:
/* line 18, ../../sass/config/_font-icons.scss */
[class^="icon"],
[class*=" icon"] {
font-family: "HW Icon Font";
font-weight: normal;
font-style: normal;
text-decoration: inherit;
-webkit-font-smoothing: antialiased;
}

requirejs configuration troubles

Due to a FUBAR directory organization in a project, I have spent some time re-organizing JS scripts on said project. The project uses requirejs and was functioning wonderfully before the re-org. However, now nothing loads when called or compiles (we use the r.js optimizer) when run -- though compiling completes without complaint. I have checked, double-checked, triple-checked, and now given in to asking for another set of eyes here on Stack Overflow.
Using RequireJS: 2.1.4 and r.js 2.1.4
The following is my configuration:
build-js.js (used for optimizer)
var requirejs = require('requirejs');
var config = {
baseUrl: './public/js',
mainConfigFile: './public/js/config/config.js',
paths: {
'requireLib': 'library/require'
},
out: ".public/js/minified/main.js",
name: "minified/main",
wrap: false,
preserveLicenseComments: false,
deps: ["app/main","modules/movie","modules/theatre"]
};
requirejs.optimize(config);
config.js
// Set the require.js configuration for your application.
require.config({
paths: {
// JavaScript folders
libs: "library",
plugins: "plugin",
app: "app",
adminlibs: "../adminassets/js/plugins/ui",
// Libraries
jquery: "library/jquery",
jqcookie: "library/jquery.cookie",
jqui: "../adminassets/js/plugins/ui/jquery-ui-1.10.0.custom.min",
jqezmark: "library/jquery.ezmark",
jqcolor: "library/jquery.color",
underscore: "library/underscore-amdjs",
backbone: "library/backbone-amdjs",
chosen: "library/chosen.jquery",
moment: "library/moment",
// Site Components
site: "app/site",
sitediscussion: "app/site-discussion",
namespace: "app/namespace",
// Plugins
text: "plugin/text",
async: "plugin/async",
use: "plugin/use",
datetimepicker: "../adminassets/js/plugins/ui/jquery.datetimepicker",
ajaxfileupload: "../adminassets/js/plugins/uploader/jquery.ajaxfileupload"
},
shim: {
'chosen': ['jquery'],
'jqcookie': ['jquery'],
'jqui': ['jquery'],
'jqezmark': ['jquery'],
'jqcolor': ['jquery'],
'site': {
deps: ['jquery','jqezmark','chosen','underscore','namespace','jqui','jqcookie'],
exports: 'site'
},
'sitediscussion': {
deps: ['jquery', 'underscore'],
exports: 'sitediscussion'
},
'jquifull' : ['jquery'],
'datetimepicker' : ['jqui'],
'ajaxfileupload' : ['jquery'],
'backbone': ['underscore','jquery']
},
// Initialize the application with the main application file
deps: ["app/main"]
});
File structure is as follows:
{site-root}/public/js
Which contains directories:
app
config
library
minified
modules
plugin
templates
All files listed above in build-js and config.js are confirmed to be in the expected folders.
requirejs is called as follows:
On dev machines (which I'm currently testing the setup on):
data-main="/js/config/config" src="/js/library/require.js"
On production (currently the minified/main file is not even being created, though it should be)
data-main="/js/minified/main" src="/js/library/require.js"
Can anyone see what I may be doing wrong? Again, there have been no changes to the site proper, the javascript, etc except in the two files (build-js.js and config.js) listed above. The only changes are that files have been physically moved in the directory structure. As a result, I'm nearly positive that I have a pathing issue somewhere, but I cannot seem to find it. Help?
Resolution has been found. I was referencing my configuration file through the data-main attribute in the requirejs include script tag at "/js/config/config". Though I declared a base-path of /public/js, the system was still attempting to use /js/config/ as my base path ( as stated in requirejs documentation that it will base-path based off your data-main attribute if a base path is not otherwise declared ). I moved my config.js file to /js and changed data-main to /js/config and now all paths are working appropriately, referencing base-path /js.
A side-note is that I did not notice the failure of files to load because of my use of Zend Framework and error handling. There were no 404 Errors and the Network tab of my dev-tools showed success in loading all .js files ... it was only when I looked at the response-content of those files that I found they were spitting out PHP error logs rather than .js content.