How to deploy SCSS file to dist in angular 6? - sass

We have a need to deploy scss files to dist directory when angular is building. I am fully aware that only css should be deployed after the build however we have custom need to read the scss file on run time and perform certain action.
I tried adding below line (last line under scripts:) in angular.json file but that did not help. I cant find any file deploying during debug.
"build": {
"builder": "#angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"src/scss/styles.scss"
],
"scripts": [
"node_modules/jquery/dist/jquery.min.js",
"node_modules/bootstrap/dist/js/bootstrap.js",
"src/scss/_custom-variables.scss"
]
},

"assets": [
"src/favicon.ico",
"src/assets",
"src/scss/_custom.scss"
],
Adding this under assets in angular.json file works for me. I was looking under wrong folder.

Out of the box; angular 6 does not provide a way to do this natively. However; you can achieve what you are describing by using custom webpack configuration that utilizes Angular 6 builders.
For example, you can use Custom Webpack Builder. Due to the nature of builders,their configuration is merged with CLI own configuration, so all you need to do is to create a minimalistic configuration utilizing Webpack Copy Plugin; then use glob patterns to catch & copy all required .scss files to dist/ directory.
You can try to fiddle with similar webpack configuration:
"use strict";
const CopyWebpackPlugin = require("copy-webpack-plugin");
module.exports = {
plugins: [
new CopyWebpackPlugin([
{
from: "src/app/**/*.scss",
to: "dist/app/"
}
]
)
]
};
Alternatively; if you do not require ejected SCSS during development and only in production package, you can use simple Gulp task to copy the files
"use strict";
let gulp = require("gulp");
gulp.task("copy:styles", () =>
gulp.src(["src/app/**/*.scss"])
.pipe(gulp.dest("dist/app/")));

Related

do you have to run npm run production when installing a new package?

I'm quite new, I need help.
https://github.com/tailwindlabs/tailwindcss-aspect-ratio
I have a laravel 8 project in production. I have installed this package and in local it works fine, but when I upload it to production it doesn't work. This package requires the installation of a plugin in the tailwind.config.js file.
const defaultTheme = require('tailwindcss/defaultTheme');
module.exports = {
purge: [
'./vendor/laravel/jetstream/**/*.blade.php',
'./storage/framework/views/*.php',
'./resources/views/**/*.blade.php',
],
theme: {
extend: {
},
},
variants: {
extend: {
opacity: ['disabled'],
},
},
plugins: [require('#tailwindcss/forms'), require('#tailwindcss/typography'), require('#tailwindcss/aspect-ratio'), ],
};
I have to run npm run production in production?
Thank you very much
does your webpack file create a .js file in the public directory? This is the file you need to upload after you run the npm run production
sometimes it helps to press ctrl when reloading as the browser may cache the old js files.

Gatsby Develop Failing using gatsby-plugin-sass

After installing the gatsby-plugin-sass module:
When I try to run gatsby build, I get the following error:
ERROR
Unknown error from PostCSS plugin. Your current PostCSS version is 6.0.23, but autoprefixer uses 7.0.26. Perhaps this is the source of the error below.
ERROR #98123 WEBPACK
Generating development JavaScript bundle failed
Browser queries must be an array or string. Got object.
File: src/indexs.sass
failed Building development bundle - 9.200s
I have been working on a resolution to this for hours. I have tried:
custom webpack rules in gatsby-node.js for sass files
reading, re-reading, and re-re-reading the instruction on gatsby's site
updating PostCSS using npm in every way I know how
So far, nothing has worked.
Why is it so complicated to get sass working with gatsby? When the documentation on gatsby's site makes it seem so easy?
Any suggestions what I can do to get this working?
in gatsby-node.js:
exports.onCreateWebpackConfig = ({
stage,
rules,
loaders,
plugins,
actions,
}) => {
// console.log('rules',rules)
// console.log('rules.css',rules.css())
// console.log('rules',rules.postcss())
actions.setWebpackConfig({
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
// Creates `style` nodes from JS strings
'style-loader',
// Translates CSS into CommonJS
'css-loader',
// Compiles Sass to CSS
'sass-loader',
],
},
],
},
plugins: [
plugins.define({
__DEVELOPMENT__: stage === `develop` || stage === `develop-html`,
}),
],
})
}
In gatsby-config.js:
{
resolve: `gatsby-plugin-postcss`,
options: {
postCssPlugins: [require(`postcss-preset-env`)({ stage: 0 })],
},
},
`gatsby-plugin-sass`,
the sass import line in gatsby-browser.js:
import "./src/indexs.sass"
Using sass instead of node-sass saved my day.
remove node-sass
npm uninstall node-sass
or
yarn remove node-sass
and add sass aka dart-sass
npm install --save-dev sass
or
yarn add sass
then edit gatsby-config.js
plugins: [
{
resolve: `gatsby-plugin-sass`,
options: {
implementation: require("sass"),
},
},
]
now run gatsby develop
:)
I'm a bit late to the party but hopefully this might help someone.
I have Sass setup and working with Gatsby without to much extra config required.
Install both node-sass and gatsby-plugin-sass via npm.
npm install --save node-sass gatsby-plugin-sass
Include gatsby-plugin-sass in your gatsby-config.js file in plugins: [] as below with any other Gatsby plugins you maybe using.
module.exports = {
siteMetadata: {
title: `#`,
description: `#`,
author: `#`,
},
plugins: [
`gatsby-plugin-sass`,
],
}
Write your styles as .sass or .scss files and import your main styles.scss (or whatever you prefer to name it) either in your main Layout.js file or gatsby-browser.js file as below using the path to the location of your styles.scss file.
import "./src/styles/styles.scss"
I hope this works for you but if you have any other trouble add a comment and I'll try to reply back.
I hope someone chimes in on this to show how exactly to set up gatsbys sass plugin. I could not get it to work at all.
But I did find a workaround in my case:
I removed gatsby-plugin-sass from the plugins array in gatsby-config.js, turning it off (but I did not uninstall it using npm)
I installed postcss-node-sass and postcss
I added this info to the plugins array in gatsby-config.js:
{
resolve: `gatsby-plugin-postcss`,
options: {
postCssPlugins: [
require(`postcss-preset-env`)({ stage: 0 }),
require(`postcss-node-sass`)(),
],
},
},
I added a custom rule for webpack in gatsby-node.js:
exports.onCreateWebpackConfig = ({
stage,
rules,
loaders,
plugins,
actions,
}) => {
// console.log('rules',rules)
// console.log('rules.css',rules.css())
// console.log('rules',rules.postcss())
actions.setWebpackConfig({
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
// Creates `style` nodes from JS strings
'style-loader',
// Translates CSS into CommonJS
'css-loader',
// Compiles Sass to CSS
'sass-loader',
],
},
],
},
plugins: [
plugins.define({
__DEVELOPMENT__: stage === `develop` || stage === `develop-html`,
}),
],
})
}

How to combine `css-modules` with normal `sass`, preferably in `webpack`

TLDR: How to combine css-modules with normal sass, preferably in webpack.
The Setup:
I am working on the styling build process for an e-commerce website. The site's styles are currently done in sass along with the js through a gulp browserify build process.
I have recently added a single page app that is built using react with webpack and babel. Inside of that application I am taking advantage of css-modules provided by webpack to scope the class names to each react component.
The problem:
I would like to incorporate the styles from the webpack css-modules build in with the main styling bundle for the site. To do this, I was considering building a webpack configuration to build the styles for the whole site. The problem I have is how to get the styles which are currently built by the single page webpack configuration and inject just the style chunk into a global webpack configuration that handles styles for the whole site. I should mention that I would like to keep the two configurations as separate as possible
The Questions:
Is there a proper way of having decoupled webpack builds where one is still able to use chunks from the other?
If so, how do I do it so that the css-module setup stays in the single page configuration, and the extract-text-webpack part along with a boring sass build goes into a global configuarion?
If not, how should I go about having one section of sass go through the css-modules workflow, and still combine it with the bundle from the rest of the site.
Thanks in advance.
EDIT
based on #Alexandr Subbotin's answer, I have updated my webpack to look something like the code below. I did have to change names and paths because of the code belongs to my employer, so there may be slight errors.
var ExtractTextPlugin = require('extract-text-webpack-plugin');
const JSDIR = './build/js/';
const STYLES = './build/css/bundle.css';
module.exports = {
entry : {
'styles' : './src/styles.scss',
'app' : './src/index.js',
// a javascript file that includes the root of the single page app.
'single-page' : './src/single-page/styles-entry.js',
},
output : {
path : JSDIR,
filename : '[name].js', // normally compiles my
publicPath: 'http://localhost:8080/',
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader : 'babel-loader',
query : {
presets: [
'react','es2015','stage-0',
]
},
},
{
test : /\.scss$/,
loader: ExtractTextPlugin.extract('style?sourceMap', 'css?-url&sourceMap!sass?sourceMap'),
exclude : /\/single-page\//,
},
{
test : /\.scss$/,
loader: ExtractTextPlugin.extract(
'style?sourceMap',
'css?-url&modules&importLoaders=1&localIdentName=SinglePage__[name]__[local]!sass?sourceMap'
),
include : /\/single-page\//,
}
]
},
plugins : [
new ExtractTextPlugin(STYLES, {
allChunks : true,
}),
],
resolve : {
alias: {
"eventEmitter/EventEmitter": "wolfy87-eventemitter",
},
extensions: ['', '.js','.jsx'],
},
}
If I understood your question you want to apply css-modules only to one part of your application and leave simple sass building process in other parts.
To do this you can use exclude and include options in loaders. I.e. if you have your single page application inside single-page directory your webpack config can be:
module: {
entry: {
// it is your global sass styles
application_css: './css/application.scss',
// it is main file of your SPA bundle. Somewhere inside you will use require('./styles.scss') that should be processed by css-modules
spa_index: './single-page/index.js'
},
loaders: [
...,
{
// This loader will build all your sass that are not in `single-page` directory
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style', 'css!sass'),
exclude: /\/single-page\//
},
{
// This loader will handle all your css module in `single-page` directory
test: /\.scss$/,
loader: 'style!css?modules!sass',
include: /\/single-page\//
},
],
...
}
So, in this case all css from single-page/ will use css modules, and the rest won't.
EDIT:
If you take a look in API section of ExtractTextPlugin documentation you find
The ExtractTextPlugin generates an output file per entry, so you must use [name], [id] or [contenthash] when using multiple entries.
In your example you have have two chunks with css (styles and single-page), but only one output ./build/css/bundle.css. If you change your output to ./build/css/[name].css your will have two css files: styles.css with your global css and single-page.css with SPA styles.

Webpack 2 - compile scss to css and miniffy, together with sourcemaps

I'm completely new to webpack (been using gulp since... forever).
However, I've just decided to use webpack. Decided to go with webpack 2 (2.1.0-beta.20 currently).
Been looking all over, still couldn't do a simple task as "give webpack my bootstrap.scss file (which imports all other bootstrap partial scss files needed) and have returned bootstrap.custom.min.css and bootstrap.custom.min.css.map".
I have my own bootstrap.scss file which only imports what I need from bootstrap (not using all of it), but after a custom custom-variables.scss file imported at the top, to overwrite some default bootstrap variables - like colors, grid columns etc. Anyway, I'm sure this is not relevant... The issue is compiling scss to css with custom output file name and sourcemap.
Not that it would make any difference, but to start with, here's my custom bootstrap.scss:
#import "custom-variables"; // to overwrite default bootstrap variables
/**
* Twitter Bootstrap
* This is actually copy/paste from the original bootstrap file, just changed paths
*/
// Core variables and mixins
#import "../../../../node_modules/bootstrap/scss/variables";
#import "../../../../node_modules/bootstrap/scss/mixins";
// and so on... only what I need. I don't need tables, forms and a few other.
In addition to this, I also have my own style.scss for which I need to do the same (to have returned style.min.css and style.min.css.map).
As for my webpack.config.js file, this is all I have:
const webpack = require('webpack');
const autoprefixer = require('autoprefixer');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const path = require('path');
const sassLoaders = [
'css-loader',
'postcss-loader',
'sass-loader?indentedSyntax=sass&includePaths[]=' + path.resolve(__dirname, './dev')
];
const config = {
entry: {
'bootstrap.custom.min': ['./wp-bootstrap'], // this file only contains 1 line: require('./dev/css/overwrite/bootstrap/bootstrap.scss');
'style.min': ['./wp-style'], // this file also contains 1 line: require('./dev/css/style.scss');
},
module: {
loaders: [
{
test: /\.scss$/,
loader: 'file',
// or, other examples I've found said to use:
// loader: ExtractTextPlugin.extract({ fallbackLoader: 'style-loader', loaders: 'css!sass' }),
// but if I try like that, I get: "Cannot read property 'query' of undefined"
query: {
name: '[name].css'
}
}
]
},
plugins: [
new ExtractTextPlugin('[name].css')
],
postcss: [
autoprefixer({
browsers: ['last 2 versions']
})
],
resolve: {
modules: [
path.resolve('./'),
'node_modules'
]
}
};
module.exports = config;
These are all the related packages I have installed:
"devDependencies": {
"autoprefixer": "^6.4.0",
"css-loader": "^0.23.1",
"extract-text-webpack-plugin": "^2.0.0-beta.3",
"node-sass": "^3.8.0",
"postcss-loader": "^0.9.1",
"sass-loader": "^4.0.0",
"style-loader": "^0.13.1",
"webpack": "^2.1.0-beta.20"
}
If I use a version of extract-text-webpack-plugin which is <2.x, then I get other errors, it's not compatible with webpack 2.
So, baby steps in the code above... Simply tried to at least obtain my bootstrap.scss and style.scss transformed into 2 separate css files: bootstrap.custom.min.css and style.min.css (don't know what to do about sourcemaps yet).
This is all I could come up with after searching google and trying to follow some examples. No solid tutorial out there that could make me understand how to use webpack for what I need to accomplish. I'm only guessing here, blind-folded.
But when I type webpack in the console and hit Enter, I don't get any css file, instead I get the following 3 files:
bootstrap.css - with the exact same content as the source
bootstrap.scss, like it just copies the file content over, instead of compiling scss to css;
bootstrap.custom.min.js which has a bunch of javascript code in
it;
style.min.js - which also has a bunch of javascript code in it.
I've been stuck here for days, didn't even get to all the rest I need (sourcemaps and a destination folder of my choosing for the css files and css.map files).

How to set up Browserify with Elixir and Browserify Shim on Laravel 5?

I am trying to set up Browserify with Elixir and Browserify Shim on Laravel 5.2 to use Gulp with my JavaScript files, but I didn't have much luck so far. This should be pretty straightforward to do, but it isn't.
Here is my package.json
{
"private": true,
"devDependencies": {
"gulp": "^3.8.8"
},
"dependencies": {
"bootstrap-sass": "^3.0.0",
"browserify-shim": "^3.8.12",
"jquery": "^2.2.0",
"jquery-ui": "^1.10.5",
"laravel-elixir": "^4.0.0"
},
"browser": {
"app": "./resources/assets/js/app.js",
"utils": "./resources/assets/js/utils.js",
},
"browserify": {
"transform": [
"browserify-shim"
]
},
"browserify-shim": {
"app": {
"depends": [
"jquery:$",
"utils:Utils"
]
},
"utils": {
"depends": [
"jquery:$"
]
},
}
}
gulpfile.js
var elixir = require('laravel-elixir');
elixir(function (mix) {
mix.browserify('main.js', './public/js/bundle.js');
});
Entry script main.js looks like this:
var $ = require('jquery');
var Utils = require('utils');
var App = require('app');
app.js
var App = {
init: function(){
console.log(Utils);
Utils.doSomething();
}
//other methods
};
In short: Utils depends on $, and App depends on both $ and Utils.
When I hit gulp from terminal, bundle.js is correctly created. All scripts are wrapped up in Browserify code (as expected). Each script has all included dependencies, like I configured in package.json so this part looks good as well.
The problem is that all my included dependencies are empty objects. For example, Utils in app.js is empty, and I get an error when I try to call its method "doSomething". Console log prints out an empty object "{}" instead of real object. The only correctly included script is jQuery and it's not an empty object.
What could be wrong here? Do I need to make some changes in my JS files or in configuration to make this work? It looks like I'm pretty close to the solution, but it still does not work and I can't use it at all.
It is the easiest solution to directly use 'exports' from browserify-shim property:
"browserify-shim": {
"app": {
"exports": "App",
"depends": [
"jquery:$",
"utils:Utils"
]
},
"utils": {
"exports": "Utils",
"depends": [
"jquery:$"
]
},
}
Take a look at this repo which I believe shows the fixed version of your app. The issue is that your app.js and utils.js modules aren't exporting anything to their respective require calls. One option is to add a line like:
module.exports = App;
to the bottom of your app.js file, and the equivalent to the bottom of your utils.js file. You'll see if you test the repo that badapp doesn't have this line and produces the exact behavior you're describing.
See this answer for an explanation of the issue.

Resources