I am trying to import jquery UI theme into my main app.css . This is what has been done so far:
bower.json
{
"name": "Softverk Webportal",
"dependencies": {
"jquery": "~2.1.1",
"jquery-ui":"~1.11.4",
},
"resolutions": {
"jquery": "~2.1.1",
}
}
_jquery_ui.scss
#import url("../../../assets/bower_components/jquery-ui/themes/base/all.css");
app.scss
#import "jquery_ui";
And my sass task in grunt looks like this:
sass: {
options: {
includePaths: [
'assets/bower_components/jquery-ui/themes/base',
]
},
dist: {
options: {
outputStyle: 'compressed',
sourceComments: 'map',
sourcemap: 'file'
},
files: {
'assets/css/app.min.css': [
settings.template.path + 'scss/app.scss',
]
}
}
},
However, when this compiles, none of the jquery ui css classes picked up . my sass version is:
Sass 3.4.13 (Selective Steve)
Can anyone suggest how to use jquery UI with grunt / sass ?
Since there wasn't any response and google search was not very helpful, i ended up doing this:
'sass-convert': {
/**
* NOTE: make sure to change the images to something like this:
* background-image: url("images/ui-icons_444444_256x240.png") --> background-image: url($template-path +"images/ui-icons_444444_256x240.png");
* */
options: {
from: 'css',
to: 'scss'
},
files: { ///home/khan/www/softverk-webportal-remaxth/assets/bower_components/jquery-ui/themes/base
cwd: 'assets/bower_components/jquery-ui/themes/base/',
src: 'jquery-ui.css',
filePrefix: '_',
dest: settings.template.path + 'scss/'
}
},
grunt.registerTask('default', [ 'sass-convert');
Which generates _jquery-ui.scss , which was then added to app.scss like this:
#import "jquery-ui";
Also in package.json , make sure to add:
"grunt-sass": "~0.12.1",
"grunt-sass-convert":"~0.2.0",
#npm install
What i did is simply import css file in my screen.scss file in a symfony project like this:
#import "../../../../../bower_components/jquery-ui/themes/vader/jquery-ui.css";
and it worked.
Related
I've just started a fresh rails-6 project with webpacker and vue. I wanted to have the vue-component styles in sass, but the sass-loader throughs:
Error: Module build failed (from ./node_modules/sass-loader/dist/cjs.js)
SassError: Invalid CSS after "": expected 1 selector or at-rule, was ".foo"
Has anyone seen this before? Or maybe, how can I debug what goes wrong here?
Component foo.vue
<template>...</template>
<script>...</script>
<style lang="sass">
.foo
margin: 0
padding: 0
</style>
Removing the initial indention of the sass code does not help.
Versions
rails 6.1.3.1
webpacker 5.2.1
node 14.16.1
Project setup
rails new --database=postgresql --skip-test foo
rails webpacker:install:vue
yarn add vue-turbolinks
rails webpacker:install:coffee
yarn add coffee-loader#1
yarn add sass-loader#10
package.json
{
"name": "foo",
"private": true,
"dependencies": {
"#popperjs/core": "^2.9.2",
"#rails/actioncable": "^6.0.0",
"#rails/activestorage": "^6.0.0",
"#rails/ujs": "^6.0.0",
"#rails/webpacker": "5.2.1",
"#tabler/core": "tabler/tabler",
"bootstrap": "^5.0.0-beta3",
"coffee-loader": "1",
"coffeescript": "1.12.7",
"sass-loader": "10",
"tabler": "^1.0.0-alpha.8",
"turbolinks": "^5.2.0",
"vue": "^2.6.12",
"vue-loader": "^15.9.6",
"vue-select": "^3.11.2",
"vue-template-compiler": "^2.6.12",
"vue-turbolinks": "^2.2.2"
},
"version": "0.1.0",
"devDependencies": {
"webpack-dev-server": "^3.11.2"
}
}
I've also added vue-select, bootstrap, and tabler. But I don't think they will interfere.
Webpack configuration config/webpack/environment.js
const { environment } = require('#rails/webpacker')
const coffee = require('./loaders/coffee')
const { VueLoaderPlugin } = require('vue-loader')
const vue = require('./loaders/vue')
environment.plugins.prepend('VueLoaderPlugin', new VueLoaderPlugin())
environment.loaders.prepend('vue', vue)
environment.loaders.prepend('coffee', coffee)
module.exports = environment
Layout application.html.haml
!!!
%html
%head
%title Foo
= csrf_meta_tags
= csp_meta_tag
= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload'
= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload'
%body
#vue_app
= yield
Pack packs/application.js
import Rails from "#rails/ujs"
import Turbolinks from "turbolinks"
import * as ActiveStorage from "#rails/activestorage"
import "channels"
Rails.start()
Turbolinks.start()
ActiveStorage.start()
import 'bootstrap'
import '#tabler/core'
import TurbolinksAdapter from 'vue-turbolinks'
import Vue from 'vue/dist/vue.esm'
Vue.use(TurbolinksAdapter)
document.addEventListener('turbolinks:load', () => {
const app = new Vue({
el: '#vue_app',
data: () => {
return {}
},
components: {}
})
})
Sass vs. SCSS
There are two syntax variants:
There are two syntaxes available for Sass. The first, known as SCSS (Sassy CSS) and used throughout this reference, is an extension of the syntax of CSS. This means that every valid CSS stylesheet is a valid SCSS file with the same meaning. This syntax is enhanced with the Sass features described below. Files using this syntax have the .scss extension.
The second and older syntax, known as the indented syntax (or sometimes just “Sass”), provides a more concise way of writing CSS. It uses indentation rather than brackets to indicate nesting of selectors, and newlines rather than semicolons to separate properties. Files using this syntax have the .sass extension.
See also: https://stackoverflow.com/a/5654471/2066546, https://sass-lang.com/documentation/syntax
Which syntax does the sass-loader use?
The sass-loader chooses the syntax according to the file extension by default:
The indentedSyntax option has true value for the sass extension.
This means that the original sass syntax (indented syntax) is only used if the file extension is .sass. Within the vue component, which has the extension .vue, the sass-loader uses the newer "scss" syntax by default.
How to configure sass-loader to use the sass syntax (indented syntax)?
The sass-loader documentation has instructions on how to specify indentedSyntax: true in the webpack configuration.
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
"style-loader",
"css-loader",
{
loader: "sass-loader",
options: {
sassOptions: {
indentedSyntax: true
},
},
},
],
},
],
},
};
However, with webpacker, the webpack configuration is composed automatically. So, one needs to modify the existing configuration object:
// config/webpack/environment.js
const { environment } = require('#rails/webpacker')
// To get an overview, have a look at `environment.loaders`.
console.log(environment.loaders)
const { merge } = require('webpack-merge')
const sassConfig = environment.loaders.find(el => el.key == 'sass')
const sassLoader = sassConfig.value.use.find(el => el.loader == 'sass-loader')
sassLoader.options = merge(sassLoader.options, {
sassOptions: {
indentedSyntax: true
}
})
module.exports = environment
This requires webpack-merge: yarn add webpack-merge.
I'm sure there are better ways to do it. Please feel free to add answers or comments!
Sass works with curly braces:
.foo {
margin: 0
}
You can try to include <%= stylesheet_pack_tag 'application', media: 'all' %> on your root HTML file.
I think it will work.
Added config files to the project (packege.json &webpack.config.json), added babel. At the moment it turns out like this: There is a directory / Scripts / build &Scripts / es6 (/main.js). When the npm run build command is run, everything builds ok (from themain.js file as indicated in the entry section of thewebpack.config.json file), the bundle.js file is created in the/ Scripts / build directory. In the above, there are no problems and everything is as it should. Now I want to use the js classes (their methods and properties) in the views (* .cshtml). How do i do this? Or need a different approach? If I write js code inmain.js, then I build it, then the code fulfills. But how do I make a function and run it (for example, by clicking a button)?
packege.json:
{
"name": "SensorDashboard",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack --progress --mode='development' -p"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^7.1.2",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.7.0",
"webpack": "^4.41.0",
"webpack-cli": "^3.3.9"
}
}
webpack.config.js
const path = require('path');
module.exports = {
entry: ['./Scripts/es6/main.js'],
output: {
path: path.resolve(__dirname, './Scripts/build'),
filename: 'bundle.js'
},
// IMPORTANT NOTE: If you are using Webpack 2 or above, replace "loaders" with "rules"
module: {
rules: [{
loader: 'babel-loader',
test: /\.js$/,
exclude: /node_modules/
}]
}
}
main.js:
import { Map, MyClass } from './Map';
(function () {
window.test_func = function () {
let cl = new MyClass();
cl.send("asd qweqwe");
};
})();
MyClass:
export class MyClass {
send(message) {
console.log(message);
}
}
then i runing command: npm run build, and a file was created (/Script/build/bundle.js)
then i try to use in *.cshtml:
#{Layout = null;}
...
<script src="~/Scripts/build/bundle.js"></script>
...
<div>....</div>
<script type="text/javascript">
$(document).ready(function () {
test_func(); //this work
let m = new MyClass(); //this don`t work (MyClass is not defined)
m.send("asd");
});
</script>
I think should be as simple as loading the script in your .cshtml file with your standard script tag at the bottom of the file which would look something like this:
#section Scripts {
<script src="#Url.Content("~/Scripts/build/main.js")"></script>
}
(possibly without the #Url.Content though I'm not 100% sure offhand)
You could then call a function by doing something like the following example, there are a few ways and probably depends on what your class looks like in your main.js:
#section Scripts {
<script src="#Url.Content("~/Scripts/build/main.js")"></script>
document.getElementById("myButton").onclick = function(){
let someClass = new Class();
someClass.DoSomething();
}
}
Let me know if I've misunderstood the question.
Edit:
Okay, sorry I did misunderstand.
Have a look at this link and see if it helps you? It looks like exactly what you need.
It has instructions on how to configure webpack to allow calling externally.
Looks as simple as adding these two lines to your output:
libraryTarget: 'var',
library: 'EntryPoint'
Where EntryPoint is the Name you want for the module .
So:
output: {
path: path.resolve(__dirname, 'dist/js'),
filename: 'app.bundle.js',
libraryTarget: 'var',
library: 'MyModule'
},
And that should allow you to just call
EntryPoint.send("asd qweqwe");
Following the github docs, I tried the following to include scss assets in my app:
app/javascript/styles/app.scss:
#import 'https://fonts.googleapis.com/css?family=Roboto:300,400,500';
body {
margin: 0;
}
app/javascript/packs/application.js:
/* eslint no-console:0 */
// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.
//
// To reference this file, add <%= javascript_pack_tag 'application' %> to the appropriate
// layout file, like app/views/layouts/application.html.erb
// Support component names relative to this directory:
var componentRequireContext = require.context("components", true)
var ReactRailsUJS = require("react_ujs")
ReactRailsUJS.useContext(componentRequireContext)
import React from 'react';
import '../styles/app.scss'
My webpack.config.js is the default webpack installs on rails. It is a combination of these 2 directories:
https://github.com/rails/webpacker/tree/master/lib/install/config/loaders/core
https://github.com/rails/webpacker/tree/master/lib/install/config/webpack
I can find the CSS config in config/loaders/sass.js:
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const { env } = require('../configuration.js')
module.exports = {
test: /\.(scss|sass|css)$/i,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
{ loader: 'css-loader', options: { minimize: env.NODE_ENV === 'production' } },
{ loader: 'postcss-loader', options: { sourceMap: true } },
'resolve-url-loader',
{ loader: 'sass-loader', options: { sourceMap: true } }
]
})
}
On doing this, I do not get any error but the stylesheet isn't imported. Serving the same file from the asset pipeline works fine.
I'm building my app using Webpack 2. I'm using PostCSS 2 for CSS modules. Here is my CSS importing configuration for Webpack:
{
test: /\.css$/,
exclude: /(node_modules)/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true,
importLoaders: 1,
},
},
{
loader: 'postcss-loader',
options: {
plugins: loader => [
require("postcss-import")({
path: './js',
addDependencyTo: webpack,
}),
require('postcss-cssnext')(),
],
},
},
],
},
Now, the problem is, that this generates really ugly class names. Example using React:
import React, {Component} from 'react';
import styles from './Element.css';
export default class Element extends Component{
render(){
return (
<div className={styles.myElement}>This is an example.</div>
);
}
}
Renders into:
<div class="_1DHVkmCxFFQMFYac-L_MIg">This is an example.</div>
Now, this is fine in production, but in development, something like class="myElement--_1DHVkmCxFFQMFYac-L_MIg" would be a lot nicer. I found a GitHub issue discussing this, but as I'm new to Webpack, I couldn't figure out how to implement their suggestion. Whatever I tried resulted in an error, where Webpack couldn't resolve the module.
I tried adding localIdentName: '[local]--[hash:base64:5]' to postcss-loader options, but that did nothing.
So, how do I retain the original class name in the generated class name?
Adding this line to the css-loader resolved it:
localIdentName: debug ? '[name]_[local]___[hash:base64:10]' : undefined,
{
loader: 'css-loader',
options: {
modules: true,
importLoaders: 1,
minimize: false, //this line!!
},
},
you can use minimize: !isDebug and isDebug is a bool to know if you are debugging or not. but setting to false should leave "nice names"
I clone this repo then put the jquery.mobile.router.js according to my folder structure. Here is my requirejs config
//bootstrap.js content
require.config({
// The shim config allows us to configure dependencies for
// scripts that do not call define() to register a module
shim: {
underscore: {
exports: '_'
},
jquery: {
exports: 'jquery'
},
backbone: {
deps: [
'underscore',
'jquery'
],
exports: 'Backbone'
},
backboneLocalstorage: {
deps: ['backbone'],
exports: 'Store'
},
jQueryMobile : {
deps:['jquery'],
exports: "jQueryMobile"
}
},
paths: {
jquery: 'js/vendor/jquery',
jQueryMobile: 'js/vendor/jquery.mobile.min',
underscore: 'js/vendor/underscore.min',
backbone: 'js/vendor/backbone',
backboneLocalstorage: 'js/plugins/localStorage',
text: 'js/plugins/text',
'jquery.mobile.router': 'js/plugins/jquery.mobile.router'
}
});
All scripts are loading fine but the jquery.mobile.router is not loading.
my floder structure is as bellow
/app
/js
|-plugins
|-jquery.mobile.router.js
/bootstrap.js
can anyone tell me what am i doing wrong? thanks in advance.
Have you call jquery.mobile.router somewhere like below
require(['jquery.mobile.router'], function () {
});