Skip to content

Instantly share code, notes, and snippets.

@darrenmothersele
Last active April 29, 2021 09:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save darrenmothersele/b77381785c0824bc33b3ca80ceea1b86 to your computer and use it in GitHub Desktop.
Save darrenmothersele/b77381785c0824bc33b3ca80ceea1b86 to your computer and use it in GitHub Desktop.
Angular Project Setup

First I run the ng new command:

ng new --minimal --style=css --routing project-name

I use the minimal option as I like to start with the bare minimum and then add back in what I need. I then open this in my IDE of choice. I currently use IntelliJ IDEA.

The first thing I do is open the CLI config angular.json and make a few changes.

First I make sure that the schematics are configured to create inline template and styles. I do this because I prefer my components to be all in one file. I find that much more productive when jumping around from component to component in my IDE. I disagree that putting the component template in *.html and the code in *.ts is separation of concerns. My opinion is that they are the same concern and highly-coupled so should be kept together. It also discourages me from creating components that are too big.

Here's the config to add. It also disables the generation of test files.

  "schematics": {
    "@schematics/angular:component": {
      "inlineTemplate": true,
      "inlineStyle": true,
      "skipTests": true,
      "flat": true
    },
    "@schematics/angular:class": {
      "skipTests": true
    },
    "@schematics/angular:directive": {
      "skipTests": true
    },
    "@schematics/angular:guard": {
      "skipTests": true
    },
    "@schematics/angular:module": {
      "skipTests": true
    },
    "@schematics/angular:pipe": {
      "skipTests": true
    },
    "@schematics/angular:service": {
      "skipTests": true
    }
  },

I then change my builder configs, and add custom webpack configuration:

This is added to build:

      "//builder": "@angular-devkit/build-angular:browser",
      "builder": "@angular-builders/custom-webpack:browser",
      
      "options": {
        "customWebpackConfig": {
          "path": "./webpack.config.js"
        }
      }

This is added to serve:

      "//builder": "@angular-devkit/build-angular:dev-server",
      "builder": "@angular-builders/custom-webpack:dev-server",

To make this work, some more npm dependencies are needed:

npm install --save-dev @angular-builders/custom-webpack @fullhuman/postcss-purgecss autoprefixer \
    postcss-discard-comments postcss-easy-import postcss-import postcss-loader postcss-scss \
    tailwindcss

I also tend to add lodash:

npm install --save lodash
npm install --save-dev @types/lodash

And I usually add these libraries (CDK, Material Dialog, AngularFire, Formly, Luxon):

npm install --save @angular/cdk @angular/material @angular/fire @ngx-formly/core angular2-text-mask \
    firebase intl-tel-input luxon text-mask-addons

NB: I use material only for the dialog service, so I need to add an option to the providers of my app.module.ts so the angular material stops warning me I'm not using material styles:

providers: [
  { provide: MATERIAL_SANITY_CHECKS, useValue: false },
],

The custom webpack configuration is added to deal with Tailwind CSS and PostCSS:

// ***
// NB: There's a possibly improved version below in webpack.config.js
const purgeCss = require('@fullhuman/postcss-purgecss')({
// Specify the paths to all of the template files in your project
content: [
'./src/**/*.html',
'./src/**/*.ts',
],
// Include any special characters you're using in this regular expression
defaultExtractor: content => content.match(/[\w-/:]+(?<!:)/g) || []
});
module.exports = config => {
return {
...config,
module: {
...config.module,
rules: [
...config.module.rules,
{
test : /\.css$/,
loader : 'postcss-loader',
options: {
ident : 'postcss',
syntax: 'postcss-scss',
plugins: () => [
require('postcss-easy-import'),
require('tailwindcss'),
require('autoprefixer'),
...config.mode === 'production'
? [
purgeCss,
require('postcss-discard-comments')({ removeAll: true })
]
: []
]
}
}
]
}
}
};
/* purgecss start ignore */
@import "tailwindcss/base";
@import "tailwindcss/components";
/* purgecss end ignore */
@import "tailwindcss/utilities";
module.exports = {
theme: {
extend: {
spacing: {
px: '1px',
'0': '0',
'1': '0.25rem',
'2': '0.5rem',
'3': '0.75rem',
'4': '1rem',
'5': '1.25rem',
'6': '1.5rem',
'8': '2rem',
'10': '2.5rem',
'12': '3rem',
'16': '4rem',
'20': '5rem',
'24': '6rem',
'32': '8rem',
'40': '10rem',
'48': '12rem',
'56': '14rem',
'64': '16rem',
'128': '32rem',
},
minHeight: {
'16': '4rem',
'24': '6rem',
'0': '0',
full: '100%',
screen: '100vh',
}
}
},
variants: {
textColor: ['responsive', 'hover', 'focus', 'disabled'],
backgroundColor: ['responsive', 'hover', 'focus', 'disabled'],
opacity: ['responsive', 'hover', 'focus', 'group-hover'],
},
plugins: []
};
const purgeCss = require('@fullhuman/postcss-purgecss')({
// Specify the paths to all of the template files in your project
content: [
'./src/**/*.html',
'./src/**/*.ts',
],
// Include any special characters you're using in this regular expression
defaultExtractor: content => content.match(/[\w-/:]+(?<!:)/g) || []
})
module.exports = (config) => {
const postCssLoader = {
loader: 'postcss-loader',
options: {
ident: 'postcss-custom',
plugins: () => [
require('postcss-easy-import'),
require('tailwindcss'),
require('autoprefixer'),
...config.mode === 'production' ? [purgeCss] : []
]
}
}
config.module.rules
.filter((r) => r.test.test('.css'))
.forEach(r => r.use.splice(-1, 0, postCssLoader));
return config
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment