Is there a way to reference a process.env.NODE_ENV in a scss file by passing it to the sass-loader in web-pack. If so anyone know how to go about this ?
Here is my webpack module lodaers array.
module: {
loaders: [
{ test: /\.js?$/,
loader: 'babel-loader',
include: path.join(__dirname, '../app'),
exclude: /node_modules/
},
{ test: /\.scss?$/,
loader: 'style-loader!css-loader!sass-loader',
include: path.join(__dirname, '../app', 'styles')
},
{
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 even tried
{ test: /\.scss?$/,
loader: 'style-loader!css-loader!sass-loader',
include: path.join(__dirname, '../app', 'styles'),
options: {
data: "$env: " + process.env.NODE_ENV + ";"
}
}
but the above broke the build.
I just want a way to access a url in my scss file depending on the environment.
It doesn't have to be via webpack any ideas would help without hard coding it.
for example:
.contact-transparent{
width: 100%;
height: 100%;
background: url(process.env.NODE_ENV+'/home-background.jpg') left center no-repeat;
}
I think you could get this done with a custom loader that you chain in before the others for your Sass files. In that loader you would check the value of NODE_ENV and do a find/replace in the Sass source, where the replaced value is based on the env. Not fancy but would get the job done. For example:
// url-by-env-loader.js
module.exports = (source) => {
const urlsByEnv = {
dev: "the-dev-host.com",
staging: "the-staging-host.com",
prod: "the-prod-host.com"
};
const urlToReplace = "the-url-in-your-sass-source.com";
const urlToUse = urlsByEnv[process.env.NODE_ENV];
const replaceRegex = new RegExp(urlToReplace, 'g');
return source.replace(replaceRegex, urlToUse);
}
Related
I´m trying to setup a uitkit template with
webpack 4
sass loader
MiniCssExtractPlugin
uikit
What I would like to achieve is that a build automatically converts sass to css and that resulting css is injected into src/index.html.
webpack.config.js
const HtmlWebPackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.html$/,
use: [
{
loader: "html-loader",
options: { minimize: true }
}
]
},
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
modules: true,
sourceMap: true,
importLoader: 4
}
},
"sass-loader"
]}
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./src/index.html",
filename: "./index.html"
}),
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
})
]
};
index.js
import UIkit from 'uikit';
import Icons from 'uikit/dist/js/uikit-icons';
import style from "uikit/src/scss/uikit.scss"
UIkit.use(Icons);
Unfortunately a build fails with
ERROR in ./node_modules/uikit/src/scss/uikit.scss (./node_modules/css-loader??ref--6-1!./node_modules/sass-loader/lib/loader.js!./node_modules/uikit/src/scss/uikit.scss)
Module build failed (from ./node_modules/sass-loader/lib/loader.js):
$inverse-base-color: $inverse-global-color !default;
Undefined variable: "$inverse-global-color".
in new_proj/node_modules/uikit/src/scss/components/base.scss (line 607, column 49)
I would be thankful if one could explain What I´m doing wrong and why sass loader cannot find the variable $inverse-global-color.
I´ve found the answer. It´s working like this:
index.js
...
import style from "./main.scss"
...
main.scss
// 1. Your custom variables and variable overwrites.
$global-link-color: #DA7D02;
// 2. Import default variables and available mixins.
#import "uikit/src/scss/variables-theme.scss";
#import "uikit/src/scss/mixins-theme.scss";
// 3. Your custom mixin overwrites.
#mixin hook-card() { color: #000; }
// 4. Import UIkit.
#import "uikit/src/scss/uikit-theme.scss";
I have the following webpack.cofig.js file
var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry: {
app: './src/main.ts',
polyfills: './src/polyfills.ts'
},
output: {
path: path.resolve('dist'),
filename: '[name].js',
publicPath: 'assets/'
},
resolve: {
// only discover files that have those extensions
extensions: ['.ts', '.js', '.json', '.css', '.scss', '.html'],
},
module: {
rules: [{
test: /\.ts$/,
exclude: /node_modules/,
loader: 'awesome-typescript-loader'
},
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader', 'sass-loader']
})
},
{
test: /\.html$/,
loader: 'html-loader'
},
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'file-loader?name=fonts/[name].[hash].[ext]?'
}
]
},
plugins: [
new ExtractTextPlugin({ filename: 'mystyle.css', disable: false, allChunks: true })
]
};
However when I run this, the css file that should be generated does not appear. I am using extract-text-webpack-plugin however this does not work. It does not throw an error, however it does not work either.
Ok I got this to work, the reason was that in my root app component (angular2) I had the following for referring to the main stylesheet.
styleUrls: ['./app.component.scss'],
This worked fine even without the scss loader (I am using the awesome typescript loader). However when I included the following
const styles = require('./app.component.scss');
Then the additional css got generated.
I am new to webpack and I'm trying to implement it in my project. I'm also using Compass for my .scss files.
I included all my scss files in my entrypoint (see the webpack configuration down below) and I have this error:
Error line 1: Function sprite-map doesn't support keyword arguments
The scss file that causes the module build to fail:
$icons: sprite-map("icons/icons-1/k/*.png", $spacing: 10px);
#each $i in sprite_names($icons) {
.k-#{$i}{
background-position: sprite-position($icons, $i, 0, 0, true);
}
}
.k-121, .k-122, .k-123, .k-124, .k-125, .k-126, .k-127, .k-128, .k-129, .k-130, .k-131, .k-132, .k-133, {
background-image: $icons;
background-repeat: no-repeat;
}
But looking at the documentation, it is possible to use keyword arguments, isn't it ?
Here is my webpack.config.js :
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: path.resolve(__dirname, 'scripts/app.js'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.s?css$/,
loaders: 'sass-loader'
},
{
test: /\.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.(jpe?g|png|gif|svg)$/,
loader: 'file-loader?name=/dist/img/[name].[ext]'
},
{
test: /\.(eot|otf|ttf|woff|woff2)$/,
loader: 'file-loader?name=dist/fonts/[name].[ext]'
}
]
},
devtool: 'source-map',
plugins: [
new HtmlWebpackPlugin()
]
};
Thanks for your help !
I'm using webpack and React with react-css-modules and scss files. When i try and build it gives me an error on every file that imports scss files -
ERROR in ./app/components/Buttons/Button.scss
Module build failed: ReferenceError: window is not defined
I have googled for a solid day and a half and have got no where! Please help!
Here's my webpack set up:
var webpack = require('webpack');
var PROD = (process.env.NODE_ENV === 'production');
var precss = require('precss');
var autoprefixer = require('autoprefixer');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var HTMLWebpackPluginConfig = new HtmlWebpackPlugin({
template: __dirname + '/app/index.html',
filename: 'index.html',
inject: 'body'
});
module.exports = {
entry: [
'./app/index.jsx'
],
output: {
path: __dirname + '/dist',
filename: PROD ? 'bundle.min.js' : 'bundle.js'
},
watchOptions: {
poll: true
},
module: {
preLoaders: [
{
test: /\.jsx$|\.js$/,
loader: 'eslint-loader',
include: __dirname + '/assets',
exclude: /bundle\.js$/
}
],
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: "babel-loader",
query: {
presets: ['es2015', 'react']
}
},
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style', ['style!css?sourceMap&localIdentName=[local]___[hash:base64:5]!resolve-url!sass?outputStyle=expanded'])
}
]
},
postcss: [autoprefixer({ browsers: ['last 2 versions'] })],
resolve: {
extensions: ['', '.js', '.jsx']
},
plugins: PROD ? [
new webpack.optimize.UglifyJsPlugin({
compress: { warnings: false }
})
] : [
HTMLWebpackPluginConfig,
new ExtractTextPlugin("styles.css", {
allChunks: true
})
]
};
Thanks in advance!
This question keeps popping up when I tried to resolve the same error for Webpack 2, scss, extracttextplugin, and react. The following worked for me.
{
test:/\.scss$/,
use:ExtractTextPlugin.extract({fallback:"style-loader",use:["css-loader","sass-loader"]}),
include:path.join(__dirname,"client/src"),
},
Hope this helps.
I think you have to change it to this, the second parameter goes as a string instead of array. Also removed the repeated use of the style loader.
loader: ExtractTextPlugin.extract('style', 'css?sourceMap&localIdentName=[local]___[hash:base64:5]!resolve-url!sass?outputStyle=expanded')
I cannot seem to get the ExtractTextPlugin working appropriately. I've never seen a CSS file. Before I tried to switch to this plugin the scss files were being bundled without issue.
var webpack = require("webpack");
var path = require("path");
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry: "./index.js",
output: {
path: "dist/",
filename: "bundle.min.js",
publicPath: "/",
sourceMapFilename: 'bundle.min.map'
},
devtool: '#source-map',
module: {
loaders: [
{
test: /\.js$/,
exclude: /(node_modules)/,
loader: ['babel'],
query: {
presets: ['es2015', 'stage-0', 'react']
}
},
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract("style", "css", "sass")
},
{
test: /\.(png|jpg|jpeg|gif|woff|woff2|svg)$/,
loader: 'url-loader?limit=8192'
}
]
},
plugins: [
new ExtractTextPlugin("bundle.css")
],
sassLoader: {
includePaths: [path.resolve(__dirname, './stylesheets')]
}
};
SCSS file make the bundle.min.js file no problem with this...
{
test: /\.scss$/,
loader: ['style', 'css?sourceMap', 'sass?sourceMap']
}
But I need the CSS text to include in a server rendered response.
Instead of ExtractTextPlugin.extract("style", "css", "sass") you'll want to use ExtractTextPlugin.extract("style", "css!sass"). The API is a little weird that way.