Setting Up a config file for PostCSS - html

I'm using PostCSS and I want to add Post-uncss. I use no task runners, just Postcss-cli. My package.json looks like this right now:
"css-clean": "npx postcss src\\css\\main.css -u autoprefixer --replace && npx postcss src\\css\\main.css -u css-declaration-sorter --replace --no-map"
It's getting rather long. I saw mentioned that PostCSS can have a config file "postcss.config.js". The only thing mentioned in the article is the skeleton:
module.exports = {
plugins: {
'autoprefixer': {},
'css-declaration-sorter': {}
}
};
The uncss documentation just says for options:
{
html: ['index.html', 'about.html', 'team/*.html'],
ignore: ['.fade']
}
I was hoping if someone has experience with using the config file to give some advice because I don't believe this feature is well documented.

You can pass plugin parameters within a postcss.config.js file like so:
module.exports = {
plugins: [
require('module-name-1'),
require('module-name-2')({
option-a: 1,
option-b: "quoted value",
}),
],
};

Related

vite does not build tailwind css

I installed tailwind and other tools using npm install -D tailwindcss postcss autoprefixer vite
I created tailwind and postcss config files using npx tailwindcss init -p
tailwind.config.js contains:
module.exports = {
content: [],
theme: {
extend: {},
},
plugins: [],
}
postcss.config.js contains:
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
My CSS file exits in css\tailwind.css and contains:
#tailwind base;
#tailwind components;
#tailwind utilities;
The CSS file is linked to my HTMl page using <link href="/css/tailwind.css" rel="stylesheet" >
When I run vite, my app starts without build errors but tailwind output is not generated.
You need to adjust a few settings, feels like you're pretty close.
Edit Tailwind.config.js
module.exports = {
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}
Start Vite building script with 'npm run dev' command.
// Open terminal
npm run dev
(Optional) Copy demo h1 property into your index file and test
<h1 class="text-3xl text-blue-700">Testing</h1>
This works for me. Once you've done what Tailwindcss says in its docs, in your vite.config.js (I tried this on JavaScript file. I am not sure if this works on TypeScript in the same way) import tailwindcss:
import tailwindcss from 'tailwindcss'
Then add tailwindcss as a PostCSS plugin like this:
css: {
postcss: {
plugins: [tailwindcss],
},
}
Once you've done that your vite.config.js will look like this:
/*Other imports*/
import tailwindcss from 'tailwindcss'
export default defineConfig({
plugins: [],
resolve: {
/*something*/
},
css: {
postcss: {
plugins: [tailwindcss],
},
},
});

nodeJS development and production environment config file loading

Based on this answer here https://stackoverflow.com/a/22524056/777700 I have set exactly the same configuration options, but it doesn't work.
My (partial) app.js file:
console.log('environment: '+process.env.NODE_ENV);
const config = require('./config/db.json')[process.env.NODE_ENV || "development"];
console.log(config);
My ./config/db.json file:
{
"development":{
"host":"localhost",
"port":"3306",
"username":"root",
"password":"",
"database":"dbname"
},
"production":{
"host":"production-host",
"port":"3306",
"username":"user",
"password":"pwd",
"database":"dbname"
}
}
Console.log outputs:
environment: development
undefined
and app crashes. Any idea why? File is there, if I remove the [...] part of require(), it does print out the db.json file, with it, it prints out undefined.
EDIT
I tried to add console.log(typeof config) just after require() to see what I'm getting and I have noticed that if I require('./config/db.json')[process.env.NODE_ENV] I get undefined, but if I require('./config/db.json')["development"] I get back proper object.
Versions:
nodeJS 6.11.4
express 4.16.2
After more debugging and searching online, I have finally found the solution. The problem is that I'm on Windows machine and I was using npm run dev command while my "dev" command looked like SET NODE_ENV=development && nodemon server.js.
Experienced eye will notice a space before &&, which added a space behind the variable development, so the variable I was comparing against was "development " and not "development" as I was thinking.
So, the original answer from other question does work and it does load proper config!
You should export configuration as a variable:
const config = {
"development":{
"host":"localhost",
"port":"3306",
"username":"root",
"password":"",
"database":"dbname"
},
"production":{
"host":"production-host",
"port":"3306",
"username":"user",
"password":"pwd",
"database":"dbname"
}
};
module.exports = config;
This way it will be found :)
If you want to do it via JSON:
const fs = require('fs')
let localConfig
try {
localConfig = JSON.parse((fs.readFileSync('./config/db.json', 'utf-8'))
} catch (e) {
console.log('Could not parse local config.')
localConfig = false
}
module.exports = localConfig
You could then add logic for production, if there's no local configuration localConfig will return false and you can look for environment variables injected at that point.
Update:
I see that you're giving the production config yourself, in that case you can just access the key you need based on the environment. Just import localConfig and use the keys you need.
Its better to use dotenv package for this
npm i dotenv
Step 1: In package.json add this
"scripts": {
"start": "nodemon app.js",
"dev": "NODE_ENV=dev nodemon app.js"
"prod": "NODE_ENV=prod nodemon app.js"
},
Step 2: Add .env.prod and .env.dev files
.env.dev
PORT=7200
# Set your database/API connection information here
DB_URI=localhost
DB_USERNAME=root
DB_PASSWORD=password
DB_DEFAULT=dbName
Step 3: Add this in config.js
const dotenv = require('dotenv').config({ path: `.env.${process.env.NODE_ENV}` });
const result = dotenv;
if (result.error) {
throw result.error;
}
const { parsed: envs } = result;
// console.log(envs);
module.exports = envs;
Step 4: Use like this when needed
const {
DB_URI, DB_USERNAME, DB_PASSWORD, DB_DEFAULT,
} = require('../config');
Now if u want for development, run
npm run dev
For prod, use
npm run prod

How to omit devDependencies when copying node_modules?

I'd like to copy only modules, which are important for application - those located inside dependencies in package.json. I'd like to omit those under devDependencies.
package.json
{
"dependencies": {
"express": "^4.13.4",
"log4js": "^0.6.33"
},
"devDependencies": {
"gulp": "^3.9.1",
"gulp-rename": "^1.2.2",
"gulp-typescript": "^2.12.1",
"typings": "^0.7.9",
"yargs": "^4.3.2"
}
}
gulpfile.js
gulp.task('copy_packages', function() {
gulp
.src('node_modules/**/*.*')
.pipe(gulp.dest('../release/node_modules'));
});
Is there any module or a smart way to distinguish which modules belongs to dependencies group and which to devDependencies?
Had the same problem...felt weird this was not considered when gulp was created.
My work around was using child_process to run npm install and specify a directory to put the node_modules directory with only the packages you need for your application.
e.g:
gulp.task('createDeployNodeModulesFolder', function(cb) {
spawn('"npm"', ['install', '--prefix', './dist/', 'package1', 'package2'], {stdio: 'inherit', shell: true}, function (err, stdout, stderr) {
console.log(stdout);
console.log(stderr);
})
.on('close', cb);
});
In your case you want only the production dependencies so you can likely use:
npm install --prefix /deployDir/ --only=prod
There will be some warnings complaining about no package.json..etc., but those are just warnings. If you really want to get rid of them, I guess you can just add a task to copy or create a package.json into the deploy directory before running npm install.
Node.js allows you to require() JSON files which will be returned as simple JavaScript objects. You can use that to only pass those modules to gulp.src() that appear under dependencies in your package.json file:
var gulp = require('gulp');
var packageJson = require('./package.json');
gulp.task('copy_packages', function() {
var modules = Object.keys(packageJson.dependencies);
var moduleFiles = modules.map(function(module) {
return 'node_modules/' + module + '/**/*.*';
});
return gulp.src(moduleFiles, { base: 'node_modules' })
.pipe(gulp.dest('../release/node_modules'));
});
use distize https://www.npmjs.com/distize .
npx distize --no-files -o {targetpath}

Webpack dev server configuration refuse to work with full path to index

Hello I am trying to understand why does webpack dev server refuse to work with full path to my index.js. (I am using webpack with babel to build reactJS.)
At the moment my webpack.config is located in the same directory as my index.js file and due to that the declaration of the entry point of my index.js is just "./index". Here is how my webpack.config looks like:
module.exports = {
devtool: 'inline-source-map',
entry: [
'webpack-dev-server/client?http://localhost:3000',
'webpack/hot/only-dev-server',
'./index'
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/static/'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
],
resolve: {
extensions: ['', '.js']
},
module: {
loaders: [{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
include: __dirname
}]
}};
With this configuration my project is build by babel and works just fine on the server!
My problem comes when I tried to specify a full path of my index.js entry point. I need that because I want to externalize the webpack and it's configuration from my FE code. To be sure that it will work I first tried not to rely that webpack.config and index.js are in the same directory but to specify the path of the index as full path name:
entry: [
'webpack-dev-server/client?http://localhost:3000',
'webpack/hot/only-dev-server',
'D:/projects/myProject/index'
]
With this config babel seem to be able to navigate to the index.js and start compiling it, but it does encounter an unexpected (for me) error during the parse:
ERROR in D:/projects/myProject/index.js
Module parse failed: D:/projects/myProject/index.js Line 1: Unexpected token
You may need an appropriate loader to handle this file type.
| import 'babel-core/polyfill';
|
| import React from 'react';
# multi main
What do I miss, why webpack makes difference between relatively configured index.js and full path one?
(I made sure that the full path is correct)
Thanks!
After a bit annoying investigation it appeared that my problem is specifying the Windows drives in uppercase. For some reason it appear that the index.js location full path should start with lowercase drive letter!
Hopefully this experience may be helpful to others.
Try using:
d:/Folder1/folder2/index.js
instead of
D:/Folder1/folder2/index.js

gulp-jshint: How to fail the build?

I want my Gulp build to fail, if there are errors in JSHint.
According to the documentation of gulp-jshint I can use the "fail reporter".
However the following does not work:
gulp.task("lint", function() {
return gulp.src(JS_SOURCES)
.pipe(jshint())
.pipe(jshint.reporter("jshint-stylish"))
.pipe(jshint.reporter("fail"));
});
The task above always returns with exit code 0, even when there are errors in JSHint.
I am using gulp 3.8.10 and gulp-jshint 1.9.0.
There are discussions in the github issues of gulp-jshint here and here ... but according those discussions I gather that above code should work with the latest versions of gulp and gulp-jshint. However it does not ...
Has anybody figured out how to fail the build properly with gulp-jshint?
TLDR;
Until GulpJS comes with a good solution in a stable release, use the workaround as suggested by Bahmutov on GitHub.
He creates a workaround, using his own filter:
var map = require('map-stream');
var exitOnJshintError = map(function (file, cb) {
if (!file.jshint.success) {
console.error('jshint failed');
process.exit(1);
}
});
gulp.task('lint', function() {
gulp.src('example.js')
.pipe(jshint())
.pipe(jshint.reporter('jshint-stylish'))
.pipe(exitOnJshintError);
});
Long answer
This question has been posted as an issue on GitHub: How to fail gulp build? #6 . Pay special attention to Bahmutov's comment.
The solution (hack) he proposes is to add his own filter and do a process.exit(1); when there are hinting errors, which looks like this:
var map = require('map-stream');
var exitOnJshintError = map(function (file, cb) {
if (!file.jshint.success) {
console.error('jshint failed');
process.exit(1);
}
});
gulp.task('lint', function() {
gulp.src('example.js')
.pipe(jshint())
.pipe(jshint.reporter('jshint-stylish'))
.pipe(exitOnJshintError);
});
This issue links to another issue Plugin doesn't fail build #10.
What they say here basically, is that Gulp should take care of the build failing.
This results in another issue which has been reported on GulpJS: Controlling failing builds #113. Which on his turn has been move to "finish then fail" #20.
The latter one has been fixed and the Gulp JS release can be tracked on: changing this #347.
So, we'll have to wait for it to be released...
In the mean time, we can use the workaround as mentioned at the top of my post in the TLDR;
I've implemented it my gulpfile.js in task scripts-app.
It works for me. I have the same gulp task:
return gulp.src(['./src/**/*.js', './docs_src/**/*.js'])
.pipe(jshint())
.pipe(jshint.reporter('jshint-stylish'))
.pipe(jshint.reporter('fail'))
and here's what happens:
$ gulp --version
[11:03:41] CLI version 3.9.0
[11:03:41] Local version 3.9.0
[14559:3392 - 0:2151] 11:03:41 [tony#tony-lin:o +1] ~/work/solo/fsstatic2 (master)
$ cat package.json
{
"name": "fsstatic2",
"version": "0.0.0",
"description": "fsstatic",
"author": "FreedomSponsors",
"devDependencies": {
"gulp": "~3.9.0",
"gulp-concat": "~2.5.2",
"gulp-linker": "~0.1.7",
"gulp-webserver": "~0.9.1",
"yargs": "~3.12.0",
"gulp-sass": "~2.0.1",
"gulp-ng-templates": "0.0.6",
"gulp-ngtemplate": "~0.2.5",
"gulp-htmlmin": "~1.1.3",
"merge-stream": "~0.1.7",
"gulp-copy": "0.0.2",
"gulp-jshint": "~1.11.0",
"jshint-stylish": "~2.0.1"
}
}
[14559:3392 - 0:2152] 11:04:01 [tony#tony-lin:o +1] ~/work/solo/fsstatic2 (master)
$ gulp jshintall
[11:04:11] Using gulpfile ~/work/solo/fsstatic2/gulpfile.js
[11:04:11] Starting 'jshintall'...
/home/tony/work/solo/fsstatic2/src/components/todo_example/todo.js
line 26 col 23 Missing semicolon.
⚠ 1 warning
[11:04:11] 'jshintall' errored after 467 ms
[11:04:11] Error in plugin 'gulp-jshint'
Message:
JSHint failed for: /home/tony/work/solo/fsstatic2/src/components/todo_example/todo.js
[14559:3392 - 0:2153] 11:04:11 [tony#tony-lin:o +1] ~/work/solo/fsstatic2 (master)
$ echo $?
1