How can I set that grunt compile all of scss to css in a folder? - gruntfile

I want that all scss files here:'sites/all/themes/uj/sass/*.scss'
be compiled here: sites/all/themes/uj/css/*.css'
The * doesn't work. Why?
And what if I have other scss files in an other folder?
Or my all scss files should be in the same folder?
This is my gruntfile.js:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
connect: {
uses_defaults: {}
},
sass: {
dev: {
options: { sourceMap: true },
files: { 'sites/all/themes/uj/css/*.css' : 'sites/all/themes/uj/sass/*.scss' }
}
},
watch: {
css: {
files: 'sites/all/themes/uj/**/*.scss',
tasks: [ 'sass:dev' ],
options: { livereload: true }
}
}
});
// Load Grunt plugins
// grunt.loadNpmTasks('');
// Default task(s).
grunt.registerTask('default', []);
// Load Grunt plugins
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-sass-globbing');
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-cssmin');
};

Related

webpack Failed to load resource using outputPath in assets/resource

I'm not very familiar with webpack.
My goal was to put all the assets inside my HTML in a specific folder.
For that, I set a new option under the rule that deals with the `type: assets/resource:
{
test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i,
type: 'asset/resource',
generator: {
outputPath: 'assets/' // this is the new option setted
}
}
It does actually work. webpack creates the folder after compiling and brings those files inside it. The problem is that the HTML file compiled doesn't understand that the assets files are inside assets/ folder.
How can I fix it?
Here is my webpack.config.js
const path = require('path')
const { merge } = require('webpack-merge')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin')
const stylesHandler = MiniCssExtractPlugin.loader
const base = {
entry: {
bundle: [
'./js/main.js',
'./css/style.scss'
]
},
output: {
path: path.resolve(__dirname, 'docs')
},
plugins: [
new HtmlWebpackPlugin({
template: 'index.html',
scriptLoading: 'module',
inject: 'body'
}),
new MiniCssExtractPlugin()
],
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [stylesHandler, 'css-loader', 'postcss-loader', 'sass-loader'],
},
{
test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i,
type: 'asset/resource',
generator: {
outputPath: 'assets/' // this is the new option setted
}
},
{
test: /\.html$/i,
use: ['html-loader']
}
]
}
}
const dev = {
devServer: {
open: false,
host: 'localhost',
watchFiles: ['./index.html']
}
}
const prod = {
output: {
clean: true
}
}
module.exports = (env, args) => {
switch (args.mode) {
case 'development':
return merge(base, dev)
case 'production':
return merge(base, prod)
default:
throw new Error('No matching configuration was found!')
}
}
So I discover it by myself, and it was kinda obvious.
Well, when webpack compiles your index.html file, it won't understand if you just give a new path for your assets final destiny.
For example, like I did:
{
test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i,
type: 'asset/resource',
generator: {
outputPath: 'assets/' // this is the new option set
}
}
In order this to work you need to specify the publicPath:
{
test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i,
type: 'asset/resource',
generator: {
outputPath: 'assets/' // this is the new option set
publicPath: 'assets/'
}
}
You're telling webpack:
Put all the assets inside outputPath.
Hey HTML, when you look for the assets, please include the publicPath before looking for it.

Webpack doesn't process TypeScript-based node_modules

I stuck for a while about importing .ts or .tsx files from the node_modules folder into the app. It turns out babel is unable to process typescript-based things from there.
Here is an example:
ERROR in ./node_modules/#ui-kit/components/Link/index.tsx 32:1
Module parse failed: Unexpected token (32:1)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| arrowName = 'down',
| linkColor
> }: IProps) => {
| const _handleClick = (e) => {
| onClick && onClick(e);
# ./node_modules/src/index.ts 10:0-37 25:0-44:2
Here is my loader for TS|TSX:
{
test: /\.(js|jsx|ts|tsx)?$/,
exclude: [/node_modules\/(?!(#ui-kit)\/).*/],
use: [
{
loader: 'ts-loader',
options: {
allowTsInNodeModules: true,
compilerOptions: {
target: __DEV__ ? 'ES2019' : 'ES5'
}
}
}
]
}
Let's open the environmet.js file. Then, remove general loaders:
// ------------------------------------
// Loaders
// ------------------------------------
environment.loaders.delete('file')
environment.loaders.delete('babel')
environment.loaders.delete('nodeModules')
Add your own by config option:
// ------------------------------------
// Loaders
// ------------------------------------
environment.config.module = {
...environment.config.module,
rules: [
{
test: /\.(js|jsx|ts|tsx)?$/,
exclude: [/node_modules\/(?!(#ui-kit)\/).*/],
use: [
{
loader: 'ts-loader',
options: {
allowTsInNodeModules: true,
compilerOptions: {
target: 'ES2019'
}
}
}
]
},
{
type: 'javascript/auto',
test: /\.json$/,
use: ['json-loader']
},
// FILE/IMAGES
{
test: /\.woff(\?.*)?$/,
use: ['url-loader?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=application/font-woff']
},
{
test: /\.woff2(\?.*)?$/,
use: ['url-loader?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=application/font-woff2']
},
{
test: /\.otf(\?.*)?$/,
use: ['file-loader?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=font/opentype']
},
{
test: /\.ttf(\?.*)?$/,
use: ['url-loader?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=application/octet-stream']
},
{
test: /\.eot(\?.*)?$/,
use: ['file-loader?prefix=fonts/&name=[path][name].[ext]']
},
{
test: /\.svg(\?.*)?$/,
use: ['url-loader?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=image/svg+xml']
},
{
test: /\.(png|jpg)$/,
use: ['url-loader?limit=8192']
}
]
}

file-loader for fonts configuration in Webpack

Project structure
/dev
-/fonts
-/css
-/vendors
-/fontawesome
-/webfonts
/dist
-/my-project
-/fonts
With file-loader for Webapck, I´m trying to compile all sass/scss with url path and moved all font files into dist/my-project/fonts/.
webpack.config.js
module.exports = env => {
...
return{
...
output: {
path: path.resolve(__dirname, 'dist/'),
},
module: {
rules: [
{
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: './my-project/fonts/',
context: './fonts/'
}
}
]
},
{
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: './my-project/fonts/',
context: 'css/vendors/'
}
}
]
}
]
}
}
}
This config manage to copy files at the right place but in the css, I got this:
#font-face{
font-family:'Font Awesome 5 Brands';
font-style:normal;
font-weight:normal;
font-display:auto;
src:url(my-project/fonts/fa-brands-400.eot); //<--instead of fonts/fa-brands-400.eot
...
}
So how to compile the right url font path in css files keeping this outPath ?
The solution is to use :
publicPath to compile path in css url font
outPath to move font files in the right directory
So...
{
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
publicPath: './fonts/', //<--resolve the path in css files
outputPath: './my-project/fonts/', //<-- path to place font files
context: 'css/vendors/'
}
}
]
}

Adding autoprefixer to webpack 2.2.1

I'm trying to add autoprefixer to webpack 2.2.1 and having issues seeing the prefixes.
I installed postcss-loader https://github.com/postcss/postcss-loader as this seems to be the listed way to handle postcss in webpack.
I'm currently using scss files which I'm importing into my react files.
example: import styles from '../../styles/header.scss';
This is handled in webpack using sass-loader.
I'm not getting any error with my setup but I'm also not seeing any autopre-fixing going on to my files ? I presume this only needs to be added in development not production ?
Here is my dev setup webpack config.
const path = require('path')
const webpack = require('webpack')
const ROOT_DIR = path.resolve(__dirname, '../app')
module.exports = {
devtool: 'eval',
entry: [
`${ROOT_DIR}/js/index`,
'webpack-hot-middleware/client'
],
output: {
path: path.resolve(__dirname, '../public'),
filename: 'bundle.js',
publicPath: '/public/'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
new webpack.DefinePlugin({
"config.ASSET_URL": JSON.stringify(process.env.ASSETS_URL),
"config.GA_TRACKING_ID": JSON.stringify(process.env.GA_TRACKING_ID)
})
],
module: {
loaders: [
{ test: /\.js?$/,
loader: 'babel-loader',
include: path.join(__dirname, '../app'),
exclude: /node_modules/
},
{ test: /\.scss?$/,
include: path.join(__dirname, '../app', 'styles'),
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: { plugins: [
require('autoprefixer')
] }
},
{
loader: 'sass-loader',
options: {
data: "$assetPath: '" + process.env.ASSETS_URL + "';"
}
}
]
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
include : path.join(__dirname, '../app', 'images'),
loader : 'file-loader?limit=30000&name=[name].[ext]'
},
{
test: /\.(ttf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/,
include : path.join(__dirname, '../app', 'fonts'),
loader: 'file-loader?name=fonts/[name].[ext]'
}
]
}
}
I had a to deal with sometime similar recently. Check if it works if you create a separate postcss.config.js file in the directory of your scss files with this in it
//postcss.config.js
module.exports = {
plugins: [
require('autoprefixer')
]
}
and in your webpack config
{ test: /\.scss?$/,
include: path.join(__dirname, '../app', 'styles'),
use: [
{loader: "style-loader"},
{loader: "css-loader"},
{loader: "postcss-loader"},
{loader: "sass-loader",
options: {
data: "$assetPath: '" + process.env.ASSETS_URL + "';"
}
}
]
},

How to use css with webpack in a rails app?

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.

Resources