How to import lesshat into every compiled .less file - gruntjs

In grunt-contrib-stylus there is a import option:
import
Type: Array
Import given stylus packages into every compiled .styl file, as if you wrote '#import '...' in every single one of said files.
options: {
compress: false,
use: [ require('kouto-swiss') ],
import: [ 'kouto-swiss' ]
},
How can I do the same thing with lesshat in grunt-contrib-less ?
Thanks

Since release 2 you can create plugins for Less easily. Thanks to Implementing preprocessing plugins you can create preprocess plugins too.
The preprocess plugin enable you to inject Less code before processing:
LesshatProcessor.prototype = {
process : function (src, extra) {
var injected = '#import "' + path.resolve(__dirname, '../') + '/node_modules/lesshat/build/lesshat.less";\n';
var ignored = extra.imports.contentsIgnoredChars;
var fileInfo = extra.fileInfo;
ignored[fileInfo.filename] = ignored[fileInfo.filename] || 0;
ignored[fileInfo.filename] += injected.length;
return injected + src;
}
};
I have created a Lesshat plugin already: https://github.com/bassjobsen/less-plugin-lesshat. After installing this plugin by running npm install less-plugin-lesshat and then your are able to run: lessc file.less --lesshat.
You can also use this plugin together with grunt-contrib-less:
grunt.initConfig({
less: {
options: {
plugins: [
new (require('less-plugin-lesshat'))()
]
},
files: {'css/test.css' : 'less/test.less'}
}
)};
Notice that you should install the latest version of Less with grunt-contrib-less until Less has updated the version number (and grunt-contrib-less uses that version).
To use the plugin now:
run npm install grunt-contrib-less
Navigate to node_modules/grunt-contrib-less/
Remove node_modules/less
Download and unzip the latest version of Less at https://github.com/less/less.js/archive/master.zip
run npm install ./less.js

Related

Rails (6.0.3.4) Webpacker (5.2.1) package import error: `Can't import the named export from non EcmaScript module`

I'm trying to import a package into my Rails 6 project – I'm on Rails 6.0.3.4 and webpacker 5.2.1 gem.
The package is installed yarn add #shopify/react-form
It's imported into the file import {useForm, useField} from '#shopify/react-form';
Now after running ./bin/webpack-dev-server
I get this:
ERROR in ./node_modules/#shopify/react-form/build/esm/validation/validator.mjs 35:25-32
Can't import the named export 'isEmpty' from non EcmaScript module (only default export is available)
And few more of the same error but different file names.
I read on another issue that adding a new rule to webpack would fix the issue, so I followed the instructions on the webpacker README:
The thing is I don't have /config/webpack/base.js, I created on anyway and created a rules directory in side the /config/webpack/ directory, so my base.js looks like this:
// /config/webpack/base.js
const { webpackConfig, merge } = require('#rails/webpacker')
const fixConfig = require('./rules/fix')
module.exports = merge(webpackConfig, fixConfig)
and the fix looks like this:
// /config/webpack/rules/fix.js
module.exports = {
module: {
rules: [
{
test: /\.mjs$/,
include: /node_modules/,
type: "javascript/auto"
}
]
}
}
I need help/guidance to figure out hot to solve this. TIA!
I managed to fix the error, this article guided me to figure out how to merge a new rule into webpack config.
Here is what environment.js looks right now:
// /config/webpack/environment.js
const { environment } = require('#rails/webpacker')
environment.config.merge({
module: {
rules: [
{
test: /\.mjs$/,
include: /node_modules/,
type: "javascript/auto"
}
]
}
})
module.exports = environment
Before it was:
const { environment } = require('#rails/webpacker')
module.exports = environment
I ended up deleting base.js and fix.js.

Source of a style tag inserted by style-loader from Webpack?

I'm using the css-loader and style-loader with Webpack. As expected, style tags get added to the head of the document, but there doesn't seem to be any way to determine which import led to a given style tag. My understanding is that the css-loader is responsible for reading the actual css files from the import, so it seems like something that should be configured with that loader. I can't find anything that would make that possible based on these docs though: https://webpack.js.org/loaders/css-loader/
I imagine there's existing plugins and loaders to handle the need I mentioned, but I couldn't find any. I was able to get this custom loader working:
In projectRoot/web_loaders/css-module-path-includer.js:
module.exports = function (content) {
return [
`/* resource: ${this.resource} */`,
content
].join('\n')
}
Updates to webpack.config.js:
module.exports = {
...
resolveLoader: {
modules: [ 'node_modules', path.resolve(__dirname, "./web_loaders") ],
},
rules: [
{
test: /\.css$/i,
use: [
'style-loader',
'css-loader',
'css-module-path-includer'
],
}
]
}
which gives you:
and then you can use something like this to track down which module in your source ultimately led to the import:
run
npx webpack --profile --json > stats.json
there was output before and after the actual json in the output that I had to edit. There's probably an argument that results in just the json being printed.
in find_dependency_root.py
import json
import sys
stats = json.loads(open('stats.json').read())
dependency = sys.argv[1]
visited = {}
dependency_chain = [dependency]
while True:
module = next(module for module in stats['modules']
if dependency in str(module['id']))
# try to account for circular dependencies
if module['issuerId'] != 0 and dependency not in visited:
visited[dependency] = True
dependency = module['issuerId']
dependency_chain.insert(0, dependency)
else:
print('\n'.join(dependency_chain))
break
python3 find_dependency_root.py antd/lib/popover/style/index.css
./src/main/resources/static/js/Root.tsx
...
./node_modules/antd/lib/popconfirm/style/css.js
./node_modules/antd/lib/popover/style/css.js
antd/lib/popover/style/index.css

where do i put config for plugin when using gruntfile-gtx

So, I have installed single page app based on npm/bower/grunt/angular.js
In the root I have gruntfile.js with this code
module.exports = function(grunt) {
var gtx = require('gruntfile-gtx').wrap(grunt);
gtx.loadAuto();
var gruntConfig = require('./grunt');
gruntConfig.package = require('./package.json');
gtx.config(gruntConfig);
// We need our bower components in order to develop
gtx.alias('build:standardversion', [
'compass:standardversion',
...
]);
gtx.finalise();
So now I have to install grunt-cache-bust plugin from here https://github.com/hollandben/grunt-cache-bust
I installed it with npm and now I don't know where to write a task for this.
Please tell me or give me a link to understand it properly
In the directory containing GruntFile.js, create a "grunt" folder if it doesn't exist.
In the "grunt" folder, create a file "cacheBust.js"
sample cacheBust.js:
module.exports = {
assets: {
files: {
src: ['index.html', 'contact.html']
}
}
}
To run cacheBust from the command line: "grunt cacheBust"

Grunt config with es6

It is possible to write grunt config files in es6 like this?
//Gruntfile.js
module.exports = function (grunt) {
var arr = [1,2,3];
arr.forEach(val => {
...
});
...
}
One possible way to do this painlessly is to use Babel's babel-register module like this:
Installation:
npm install babel-register --save-dev
.babelrc:
{
presets: ["es2015"]
}
Gruntfile.js:
require('babel-register')
module.exports = require('./Gruntfile.es').default
Gruntfile.es
export default function(grunt) {
grunt.initConfig({})
}
GruntJS is a javascript based application. It runs under the node/iojs process and adheres to the capabilities of that environment. If you use iojs or a node version that supports these features, then yes, its possible.

Customize semantic-ui using Bower and Grunt

My project uses Bower to install deps and Grunt to build. My project tree looks like this
|
|-bower_components
| |
| |-jquery
| |-semantic
| |-...
|-Bower.json
|-Gruntfile.js
|-public
| |
| |-css // Compiled, concatenated and minified semantic-ui
| |-js // and other libs should be here
|-...
|-etc..
Is it possible to build custom semantic-ui (ie customize fonts, colors, remove unused components) using Grunt (or maybe using Gulp called from Grunt)?
Where to place semantic theme config and overrides files?
It's not difficulty to use grunt to build semantic-ui. I don't know about bower, but this is how I did it.
Install grunt-contrib-less.
Create a new directory somewhere in your project, e.g. '/less/semantic'. Copy 'site' directory from your semantic packagea, i.e. 'bower_components/semantic/src/site' to the new directory. All your overrides will be done here.
Create a config.json file in '/less/semantic' to configure what components you want to be included in your build. The file content will be something like this:
{
"elements": ["button", "divider"],
"collections": ["form"],
"modules": ["checkbox"]
}
Add following to your gruntFile.js file:
var fs = require('fs');
// Defines files property for less task
var getSemanticFiles = function() {
var files = {};
var config = JSON.parse(fs.readFileSync('less/semantic/config.json'));
var srcDir = 'bower_components/semantic/definitions/';
var outputDir = 'less/semantic/output/';
for (var type in config) {
config[type].forEach(function(ele) {
files[outputDir + type + '.' + ele + '.output'] = [srcDir + type + '/' + ele + '.less'];
});
}
return files;
};
Configure less task as following:
less: {
semantic: {
options: { compile: true }
files: getSemanticFiels()
},
dist: {
options: { compile: true }
files: { 'public/css/semantic.css': ['less/semantic/output/*'] }
}
}
Edit theme.config in 'bower_components/semantic/src', change #siteFoler to '../../../less/site/', and make any additional changes as needed per semantic document.
You run grunt less:semantic to compile all needed components, and then run less:dist to put them into a single css file.
Of course you can configure a watch task to automate the process. Then every time you make a change, the css will be automaticly re-built.
I am sure someone will build a grunt build to semantic one day, but for now, I just use this to call all the gulp commands using grunt. https://github.com/sindresorhus/grunt-shell. Just make sure you are calling the gulp build task and not the default gulp task. It has a watch task that will cause grunt to not finish the shell task.

Resources