How can i compile less in efficiently on the browser? I'm using this code to compile less on the browser but this is taking very long time in compilation. I need to compile it on the browser not in back-end.
<script>
less = {
env: "development",
logLevel: 2,
async: false,
fileAsync: false,
poll: 1000,
functions: {},
dumpLineNumbers: "comments",
relativeUrls: false
};
</script>
<script src="http://cdn.storehippo.com/assets/less-1.5.0.js"></script>
<script src="lessfile.less"></script>
In fact your question is very broad. Why do you have to compile your code client side? How does you code look? What, if any, changes when you compile you code again?
See also:
how to optimize Less CSS? how to generate 1 minified version of all less files? I am also using modifyVars
Is it faster to precompile less?
In most cases you should not use Less in a product environment. When you do for some reason you can try to optimize compile time.
You are using env: "development", that option prevent Less from caching the compiled code.
Every #import directive in your code requires an file that has to be open and read over http.
Consider to split your code into a static part (compile css) and dynamic part that have to be compiled for every request.
update
Also see: https://github.com/less/less.js/issues/2339 if your are using Safari:
You can re-enable chunking with {chunkInput: true} in the less options
(or data-chunk-input="true" attribute on the less link).
Related
For a new project I am bound to keep things webpack-only, and thus need to find a way to efficiently compile our stylesheets. Basically in a very gulh-ish way:
gather all less-files including glob-patterns like src/**/*.less (css order may be arbitrary)
also allow import of css files like, say ../node_modules/vendor/**/*.css or 3rdparty/master.less
(If I have to setup a bogus.js entry point for that, fine...)
And with all of that, a typical gulp workflow:
transpile less to css
merge (concat) less and css
have cssnano do its optimization job, with specific css nano options like e.g. orderedValues: false, normalizeWhitespace: true ...
write styles.css as final output
And of course:
have source-maps survive that chain for a styles.css.map
efficient watching and the usual lazy/incremental compilation (as gulp and webpack have it)
Something I do not need is css modules (css imported into node modules for 'scoped' use, coming out as hash-scoped selectors...)
How can a 'typical' less|css-processing toolchain be done in Webpack?
This SO question has my first attempt where I got stuck in config hell right in the middle after combining...
considerations so far (helpful or not)
I know, to webpack, any ressource including css or even font and images is a "module"... Rather than merging my css 'modules' with with actual js (only to later painstakingly separate them again later again), it might be wiser, to have an entry point cssstub.js in parallel – also known as multi-compiler mode.
But that's really, where my wisdom ends... doing a sequence of $things on a set of files in webpack seems really hard (unless it's a connected javascript module graph). I did find something on globbing, but that's not enough (merge css, cssnano,...) and mostly I simply can't glue the pieces together...
I have used gulp to build less and create corresponding maps like below:
First step compiles less and generated css in tmp folder
gulp.task('compile-less', function () {
gulp.src('./*.less') // path to your file
.pipe(less().on('error', function(err) {
console.log(err);
}))
.pipe(gulp.dest('./tmp/'));
});
Second step minifies generated css and create map files
gulp.task('build-css', ['clean'], function() {
return gulp.src('./tmp/**/*.css')
.pipe(sourcemaps.init())
.pipe(cachebust.resources())
.pipe(sourcemaps.write('./maps'))
.pipe(gulp.dest('./compiled/css'));
});
If you want you can add additional step to conact generated css.
Hi there I have been forced to come here due to every resource out there on the topic is very poor and incomplete.
Not only on the babel site but every single post out there is not complete and informative enough.
I tried to reach out at the babel forum and no replies.
I am trying to convert my prototype libraries to Es6 and convert to the most leanest possible code. So no bloaty duplicated generated code and if possible no bloaty requirejs and whatever browserify generates.
I have tried to make a project with grunt and babel directly, configure the external-helpers plugin according to the babel documentation.
It fails to include the relevant helper code and fails to include the import module code altogether.
ie a babel config like
{
options: {
sourceMap: false,
presets: ['es2015'],
"plugins": ["external-helpers"]
},
dist: {
files: {
'build/<%= package.name %>.js': ['src/<%= package.name %>.js']
}
}
}
The main project file has an import like
import Button from './ui/buttons/Button';
The module code looks like this as if the export is placed underneath extra code is generated for that.
export default class ShareButton {}
produces an output like this
Object.defineProperty(exports, "__esModule", {
value: true
});
require('babel-core/external-helpers');
var _Button = require('./ui/buttons/Button');
var _Button2 = babelHelpers.interopRequireDefault(_Button);
No source of the module or the helper object is included.
I searched hard for how to deal with external-helpers and it suggests it has to be imported into a separate file ie something like this to generate only the helper functions needed
babel-external-helpers -l createClass > src/helpers.js
But any resource regards to this fails to go as far as to how to import that into the project.
If I use the transform-runtime plugin, it produces a massive polyfill that cannot be disabled so a bug and not so useful for what I need.
"plugins": [
["transform-runtime", { "polyfill": false, "regenerator": false }]
]
If I use browserify / babelify it makes a royal mess and duplicates code still.
A config like
{
options: {
"transform": [["babelify", {
"presets": ["es2015"],
"plugins": ["external-helpers"],
sourceMap: false
}]]
},
dist: {
files: {
'build/<%= package.name %>.js': ['src/<%= package.name %>.js']
}
}
}
Produces code like this still with the external helper missing and duplicated code not relevant to the helper. ie
Object.defineProperty(exports, "__esModule", {
value: true
});
Is within every module in the generated file.
If I export the classes like this at the bottom of every file
export default class {}
Duplicated code is generated like
var _class = function _class() {
babelHelpers.classCallCheck(this, _class);
};
exports.default = _class;
In terms of filesize that doesn't include bloaty wrapping code like
},{}],2:[function(require,module,exports){
It seems concatting all the prototype classes files together to bundle in one file is the winner still.
So trying to port the library but keep it similar and bundle it together into one file.
Hopefully this is concise enough and there is a simple solution.
FYI browsers do not understand tabs and 4 spaces. I had to edit this post in my editor to get the code blocks working ! It would be nice to have a markup like other places like "```" ?
Let me know thanks.
I'm using rollup with babel now. Rollup produces a clean output as umd mode. Browserify is really bloaty in itself.
There is just a problem with polyfills being converted. I have to concat external ones in like for WeakMap.
I had a problem trying to use the generated Iterator and finding a polyfill for that so I have to code loops a particular way it doesn't generate Iterators.
The polyfill generation in babel is still too bloaty and crazy. It's pretty terrible. So I concat in minified polyfills that are very small and it's used globally.
I was running into something very similar. Was tired of trying to do it the "right way" and ended up just creating https://www.npmjs.com/package/grunt-babel-helpers which simply manipulates the string output.
I am trying to learn about technologies including Grunt, Gulp, Webpack, Browserify, but I did not feel that there is much difference between them.
In other words, I feel Webpack can do everything that a task runner does. But still I got a huge examples where gulp and webpack are used together. What's the reason?
I might be taking things in the wrong direction. Am I missing anything? If so, what?
Grunt and Gulp are actually task runners, and they have differences like config driven tasks versus stream based transformations. Each has its own strengths and weaknesses, but at the end of the day, they pretty much help you create tasks that can be run to solve a larger build problem. Most of the time, they have nothing to do with the actual run-time of the app, but rather they transform or they put files, configs and other things in place so that the run time works as expected. Sometimes they even spawn servers or other processes that you need to run your app.
Webpack and Browserify are package bundlers. Basically, they are designed to run through all of a package's dependencies and concatenate their source into one file that (ideally) can be used in a browser. They are important to modern web development, because we use so many libraries that are designed to run with Node.js and the v8 compiler. Again, there are pros and cons and different reasons some developers prefer one or the other (or sometimes both!). Usually the output bundles of these solutions contain some sort of bootstrapping mechanisms to help you get to the right file or module in a potentially huge bundle.
The blurred line between runners and bundlers might be that bundlers can also do complex transformations or trans-pilations during their run-time, so they can do several things that task runners can do. In fact, between browserify and webpack there's probably around a hundred transformers that you can use to modify your source code. For comparison, there's at least 2000 gulp plugins listed on npm right now. So you can see that there are clear (hopefully... ;)) definitions of what works best for your application.
That being said, you might see a complex project actually using both task-runners and package bundlers at the same time or in tandem. For example at my office, we use gulp to start our project, and webpack is actually run from a specific gulp task that creates the source bundles that we need to run our app in the browser. And because our app is isomorphic, we also bundle some of the server code.
In my humble opinion, you might want to get familiar with all of these technologies because chances are you will see (use) all them in the course of your career.
I've just created my own task runner/bundler.
It's simpler to use than gulp and probably webpack (although I've never used webpack).
It's very simple and has babel, browserify, uglify, minify, and handlebars out of the box.
The syntax looks like this:
const Autumn = require("autumn-wizard");
const w = new Autumn();
//----------------------------------------
// CSS
//----------------------------------------
var cssFiles = [
'./lib/pluginABC/src/css/**/*.{css,scss}',
];
w.forEach(cssFiles, srcPath => {
var dstPath = w.replace('/src/', '/dist/', srcPath);
dstPath = w.replace('.scss', '.css', dstPath);
dstPath = w.replace('.css', '.min.css', dstPath);
w.minify(srcPath, dstPath, {
sourceMap: useSourceMap,
});
});
//----------------------------------------
// BUNDLE THE JS MODULE
//----------------------------------------
var srcPath = "./lib/pluginABC/src/main.js";
var dstPath = "./lib/pluginABC/dist/bundled.min.js";
w.bundle(srcPath, dstPath, {
debug: useSourceMap,
});
//----------------------------------------
// CREATE THE HANDLEBARS TEMPLATES
//----------------------------------------
var tplPaths = [
"./lib/pluginABC/src/templates/**/*.hbs",
];
dstPath = "./lib/pluginABC/dist/templates/bundled.js";
w.precompile(tplPaths, dstPath);
And the doc is here: https://github.com/lingtalfi/Autumn
Hopefully it helps.
I'm looking for a plugin chain to use with Gulp that provides:
source map support
less
minification
concatenation
URL replacement (rebase) to address relocation/concat
I currently have the first four, but I can't find a combination of existing plugins that will give me the last (URL rebasing) also. I've not found any URL rebasing plugins that emit sourcemaps.
Just to be clear, my issue is that when I compile multiple small CSS files from my project development folders, and output them into a common folder, the move resulting from concatenation breaks relative URLs, such as those for background images.
EDITS:
It sounds like the tool chain I currently use is already intended to solve this problem. So, that's ostensibly the answer. However, that raises another question, how the required syntax is supposed to work.
That question theoretically has lots of duplicates out there:
clean-css #152: Rebasing functionality very frustrating
clean-css #195: root option on Windows
clean-css #263: How to get relativeTo option working with CSS files in different paths
http://adilapapaya.com/docs/clean-css/#howtorebaserelativeimageurls
Grunt cssmin rebasing a relative URI?
Unfortunately no answers actually explain the syntax, they just demonstrate voodoo; so I don't know why the following isn't working. If I can get it resolved I'll come back here and flag this accepted to indicate this tool chain does actually do what I need.
The source files:
/assets
/site
styleInput1.less "url(../site/logo.png)"
logo.png
background.png
/application
styleInput2.less "url(../site/background.png)"
The gulp task:
gulp.task(filename, function () {
return gulp.src(files)
.pipe(sourcemaps.init())
.pipe(less())
.pipe(minifyCss({ relativeTo: './compiled' }))
.pipe(concat(filename))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('./compiled'));
});
The output, with broken URLs. Note the multiple defects. Although the CSS is raised a directory level relative to the required assets, an additional parent directory has been added (!). Also, one of the URLs has had a hard asset folder name changed (!). Very strange:
/compiled
styleOutput1.css "url(../../compiled/logo.png)"
styleOutput2.css "url(../../site/background.png)"
My apologies for continuing the voodoo, but here is my working gulp pipe:
.pipe(minifyCss({ relativeTo: './compiled', target: './compiled' }))
And the correct output:
/compiled
styleOutput1.css "url(../assets/site/logo.png)"
styleOutput2.css "url(../assets/site/background.png)"
I personally use gulp-minify-css and specify the relativeTo attribute.
gulp.task('css', function() {
gulp.src('./assets/css/main.css')
// Here I specify the relative path to my files
.pipe(minifyCSS({keepSpecialComments: 0, relativeTo: './assets/css/', processImport: true}))
.pipe(autoprefixer({
browsers: ['last 2 versions'],
cascade: false
}))
.pipe(gulp.dest('./assets/css/dist/'))
.pipe(notify({
"title": "Should I Go?",
"subtitle": "Gulp Process",
"message": '<%= file.relative %> was successfully minified!',
"sound": "Pop",
"onLast": true
}));
});
If that doesn't work for you, they have a lot of other parameters to rebase URLs : https://github.com/jakubpawlowicz/clean-css#how-to-use-clean-css-programmatically
Notably:
rebase - set to false to skip URL rebasing
relativeTo - path to resolve relative #import rules and URLs
restructuring - set to false to disable restructuring in advanced
optimizations
root - path to resolve absolute #import rules and rebase relative
URLs
app.use(express.compiler({ src: __dirname + '/public', enable: ['less'] }));
That's the line in my app.js that enables less. How can I pass the { compress: true } parameter to it?
I also had this problem and thought this can be useful to share with others:
var lessMiddleware = require('less-middleware');
app.use(lessMiddleware({ src: __dirname + '/public', compress: true, optimization: 2 }));
More information and settings about the minify-process can be found in the Less-Middleware README.md
use less4clients with the compress option
I deprecated and removed the less4clients package which extends a express.js server with a less css rendering middleware to render less files to css on the fly (and cache the results in memory) in favor of a newer project of mine called DocPad that lets you use any pre-processor you want.
As of this time of writing, it does not have an easy to use express middleware like less4clients, however such a thing is on the roadmap soon. Instead you can use it standalone or via its API.
In hindsight I should have kept less4clients available and just stated in it's readme that DocPad is the new way of doing things, but I never realised less4clients was actually being used by anyone as DocPad has already gained so much attention.
Sadly, you can't and use connect's compiler to do it. The connect.compiler, which is what express.compiler is, only allows you to set which compilers to use, but not any options for the individual compilers. If you want to set less.js's compress flag you will need to create you're own middleware that user the less.js module.