I have a main.less file that I'm trying to compile with font-awesome classes.
My less file is very simple :
#import "../bower_components/bootstrap/less/bootstrap.less";
#import "../bower_components/fontawesome/less/font-awesome.less";
.button {
.btn;
.btn-sm;
.btn-primary;
span {
.fa;
.fa-folder-open;
}
}
I use the less compiler provided by grunt-contrib-less.
The output is :
>> NameError: .fa-folder-open is undefined in less/main.less on line 10, column 3:
>> 9 .fa;
>> 10 .fa-folder-open;
>> 11 }
Warning: Error compiling less/main.less Use --force to continue.
Aborted due to warnings
Less version : 1.7.4
Grunt-contrib-less version : 0.11.4
Font-awesome version : 4.1.0
Where is the problem ?
The only solution i found is to modify Font-awesome's less file icons.less.
I replaced
.#{fa-css-prefix}-home:before { content: #fa-var-home; }
with
.#{fa-css-prefix}-home { &:before { content: #fa-var-home; } }
Related
I know this kind of question has been asked before but they are related to third party libraries, mine is related to requireNativeComponent
I have created a React Native Component from a Native iOS component
Here is my iOS code
CanvasView File
class CanvasView: UIView {
var lines = [[CGPoint]]()
override init(frame: CGRect) {
super.init(frame:frame)
backgroundColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 0)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func draw(_ rect: CGRect) {
super.draw(rect)
guard let context = UIGraphicsGetCurrentContext() else {
return
}
context.setStrokeColor(#colorLiteral(red: 0.9529411793, green: 0.6862745285, blue: 0.1333333403, alpha: 1))
context.setLineWidth(10)
context.setLineCap(.butt)
lines.forEach { (line) in
for(i,p) in line.enumerated() {
if i == 0 {
context.move(to: p)
} else {
context.addLine(to: p)
}
}
}
context.strokePath()
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
lines.append([CGPoint]())
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let point = touches.first?.location(in: nil) else {
return
}
guard var lastLine = lines.popLast() else {return }
lastLine.append(point)
lines.append(lastLine)
setNeedsDisplay()
}
}
Canvas.swift File
import Foundation
#objc(Canvas)
class Canvas: RCTViewManager {
override func view() -> UIView! {
return CanvasView()
}
override class func requiresMainQueueSetup() -> Bool {
return true
}
}
Canvas.m file
#import <Foundation/Foundation.h>
#import "React/RCTViewManager.h"
#interface RCT_EXTERN_MODULE(Canvas, RCTViewManager)
#end
Here is my JS code
const Canvas = requireNativeComponent('Canvas');
const App = () => {
return (
<View style={styles.container}>
<Canvas style={styles.bottom} />
</View>
);}
the code works fine, but even when I do some change in my react native code and do command+s to do fast refresh I keep getting error saying Tried to register two views with the same name Canvas, but when I run npx react-native run-ios, the code works fine. So all in all hot reloading or fast refresh is not supported when I include Native component created by me even though I am not changing the native component. I can understand if I change something in iOS swift or objective c code then I need to re-run npx react-native run-ios but even after no changes in iOS side and doing only changes in JS side I keep getting this error. There are not two views with same name of Canvas in my project. I also tried clearing watchman, deleting package.json and reinstalling npm modules and pod
Same issue happens on android side as well
When fast refresh runs, this line is executed again:
const Canvas = requireNativeComponent('Canvas');
And that's where the "Tried to register two views with same name" error comes from. There are a couple of ways to fix this.
Move that line to its own file and export it: export const Canvas = requireNativeComponent('Canvas');, and then import it where you want to use it. You'll still get the same error if you save the new file that contains this line, but you typically won't change this file so it usually won't be an issue.
Guard against the native component being registered (via requireNativeComponent) multiple times. It's a bit ugly, but you can do this by storing it in the global scope: const Canvas = global['CanvasComponent'] || (global['CanvasComponent'] = requireNativeComponent('Canvas'));
I think that issue is not from the native module. it is from register the same package two times.
go to project root and run the below command
npm list
find the package by ctrl+f which you think that is creating problem like Canvas
remove that second package which is using the same package which is creating problem like Canvas
or
you can fork that package and add that package in peer dependency and use that package from your git
So I was having this issue until I realized that the app throwing an error on fast refresh makes perfect sense since the native UI cannot hot reload at runtime. You can update your React components since your components can remount at runtime, thereby hot-reloading.
If you try to refresh Swift or Obj-C, you are making a second instance of your data, so an error is thrown before that can happen.
The quick solution is to simply press "r" on your keyboard on the terminal where you're running the metro bundler. And you would have to do this wherever you are using a native component.
I'm trying to pass a version string from gulp to less, as demonstrated in the following example project:
package.json:
{
"name": "webui",
"version": "0.0.0",
"private": true,
"devDependencies": {
"gulp": "^3.9.0",
"gulp-less": "^3.0.5"
}
}
gulpfile.js:
var gulp = require('gulp');
var less = require('gulp-less');
var LESS_PARAMS = {
globalVars: {
webUiVersion: '0.0.0'
}
};
gulp.task('less', function() {
return gulp.src('test.less')
.pipe(less(LESS_PARAMS))
.pipe(gulp.dest('.'))
})
test.less:
.test {
background: url("test.jpg?v=#{webUiVersion}")
}
When running gulp less, the generated test.cssfile looks like this:
.test {
background: url("test.jpg?v=0 0");
}
As you can see, gulp-less somehow transformed 0.0.0 into 0 0. If I use a simple string without dots or 0, like 123asdf, the replacement works fine. Also, directly calling
lessc --global-var='webUiVersion="0.0.0"' test.less
on the command line produces the desired result.
So my questions are:
Is this intentional behaviour or a bug?
Is there a way to work around this issue?
I've found a way to fix this issue: The trick is to enclose the string that should be passed to less in quotes, that is writing webUiVersion: '"0.0.0"' instead of webUiVersion: '0.0.0' in gulpfile.js.
The reason for this has been pointed out by seven-phases-max below: The value of webUiVersion is directly passed to less. Without the quotes, 0.0.0 is parsed as two numbers, namely 0.0 followed by .0, which results in 0 0 in the generated CSS.
If I call:
.somemethod({
&:extend(.flex all);
});
then it appears as if less do not complain but it does generate the appropiate css either.
Is this a bug ? Has it been resolved? I am still on 2014 Java version of less, might need an update if it's worth it.
Edit, added the method somemethod:
.somemethod(#mx){
#mx();
}
.flex {
color:blue;
}
body > main {
.somemethod({
&:extend(.flex all);
});
}
I'm using dotless to compile an older version of Boostrap (2.3.2)
my main.less file looks like this
#import "less/variables.less";
.bootstrap {
#import url("less/bootstrap.less");
#import url("less/responsive.less");
}
When compiling it i get the error
.box-sizing is undefined on line 158 in file 'mixins.less': [157]:
min-height: #inputHeight; // Make inputs at least the height of their
button counterpart (base line-height + padding + border) [158]:
.box-sizing(border-box); // Makes inputs behave like true block-level
elements
--^ [159]: } [Done - Failed]
But if I do this it works,
#import "less/variables.less";
.bootstrap {
background-color: #white
}
Any ideas of whats wrong?
Thanks
== EDIT ==
It seems to be the enclosing of .boostrap that is the issue, when simply having
#import url("bootstrap.less");
#import url("responsive.less");
in my main.less everything works fine
consider:
mixin() {
#color: red;
}
p {
color: #color;
}
outputs:
NameError: variable #color is undefined
but:
.mixin() {
#color: red;
}
p {
.mixin();
color: #color;
}
outputs:
p {
color: red;
}
the .mixin call leaks #color inside the scope of p, see also: http://lesscss.org/features/#mixins-as-functions-feature
Solved this using winless (http://winless.org/) instead of dotless, didn't need to change anything in my less definition.
I'm trying to use Font-awesome in the same way I do with Bootstrap, in accordance with the semantic principles of web design (not putting billions of non-semantic classes in my HTML tags), using LESS.
It seems that it is impossible : the icon definitions are like that :
.#{fa-css-prefix}-home:before { content: #fa-var-home; }
This isn't a mixin definition but a classical CSS rule build with LESS variables.
So, i'm unable to do this kind of declaration :
.meaning-class-name {
.fa-home;
}
Lessc complain that .fa-home is undefined.
Is it a way to avoid to rot my HTML code ? Is there a way to attribute a class to an other class with less ?
Thanks !
I found that the better solution were to modify font-awesome/less/icons.less and rewrite the declarations according this pattern :
.#{fa-css-prefix}-home { &:before { content: #fa-var-home; } }
It is similar to the glyphicons.less used by Bootstrap.
PS : In Eclipse, this can be done quickly with the find/replace tool :
Find :
\.#\{fa-css-prefix\}-([-0-9a-zA-Z]+):before \{ content: #([-0-9a-zA-Z]+); \}
Replace :
.#{fa-css-prefix}-$1 { &:before { content: #$2; } }
and
Find :
\.#\{fa-css-prefix\}-([-0-9a-zA-Z]+):before,
Replace :
.#{fa-css-prefix}-$1,