Giter Club home page Giter Club logo

baumeister's Introduction

GitHub version Build Status Code of Conduct

Sorry, this project is unmaintained 😢

We recommend the following tooling:


Baumeister – The frontend build workflow for your needs

Baumeister Logo

Baumeister is here to help you to build your things. From Bootstrap themes over static websites to single page applications. Baumeister provides:

  • a file structure with focus on maintainability and upgradability
  • a build setup based on webpack and npm scripts with the following »features«
    • generate static sites with ease using handlebars templates
    • transpile, bundle and minify your code
      • ES6 as well as Sass
    • visualize size of bundled files with an interactive zoomable treemap
    • remove console output and debugger statements in production files
    • add vendor prefixes
    • lint JavaScript, Sass and HTML
    • optimize images (lossless)
    • start a local server
    • delete unused CSS (optional)
    • check for known vulnerabilities in dependencies
    • release new versions
    • run unit tests and create coverage reports
    • web performance optimization fundamentals
    • automatically format code
    • and more.

Baumeister mainly uses webpack at its core for transpiling, bundling and minifying files and provides npm scripts for working with the project. Besides that we have defined a few npm scripts to handle things like our release workflow. All necessary dependencies are installed locally via npm.

Table of Contents

Quick install guide

For those already using Node.js.

via Yeoman

See: https://github.com/micromata/generator-baumeister for details.

$ npm i -g yo
$ npm i -g generator-baumeister
$ yo baumeister
$ npm start

See Build Workflow and npm scripts for the main scripts.

via Git

$ git clone https://github.com/micromata/baumeister.git
$ cd baumeister
$ npm install
$ npm start

See Build Workflow and npm scripts for the main scripts.

Dependencies

  • Node.js (>=6.0.0)

Node.js

The major dependency is Node.js including the bundled package manager called »npm«. The projects dependencies are locally installed with npm.

Please enter the following in your terminal if you aren’t sure about the availability of Node.js and npm on your machine:

node --version

This should return something like the following in case Node.js and npm is already installed:

v8.9.4

If this isn’t the case you have to install Node.js first. On OS X we strongly recommend installing Node via Homebrew or the Node Version Manager. Not just because it’s easier to switch versions but also because you prevent potential permission problems when running npm. See detailed instructions.

Setting up the project

Navigate to the root of your installation:

cd path/to/your/installation/of/baumeister

and install the dependencies via:

npm install

npm will look at the package.json file and automatically fetch and install the necessary local dependencies needed for our build workflow as well as the required frontend dependencies to a node_modules directory.

Adjust settings via the Baumeister configuration file

You can change the most important settings without touching any webpack config by editing Baumeisters JSON based configuration. You are free to choose to store your settings either in a file called baumeister.json (respectively .baumeister.json) or in a baumeister key in your package.json file.

{
	"useHandlebars": true,
	"purifyCSS": {
		"usePurifyCSS": false,
		"whitelist": [
			"*navbar*",
			"*modal*",
			"*dropdown*",
			"*carousel*",
			"*tooltip*",
			"open",
			"fade",
			"collapse",
			"collapsing",
			"in"
		]
	},
	"generateBanners": false,
	"cacheBusting": true,
	"vendor": {
		"bundleCSS": [],
		"includeStaticFiles": []
	},
	"webpack": {
		"DefinePlugin": {
			"development": {
				"PRODUCTION": false
			},
			"production": {
				"PRODUCTION": true
			}
		},
		"ProvidePlugin": {
			"$": "jquery",
			"jQuery": "jquery"
		}
	}
}

vendor.bundleCSS and vendor.includeStaticFiles make it possible to include additional dependencies without touching any webpack config. These settings are explained in depth in the section Using external libraries within this document.

The ramifications of changing the useHandlebars setting are explained in the section Writing markup (static sites vs. single page apps).

Adding banners describes the effects of setting generateBanners to true.

Define global constants at compile time

If you want to provide constants for different types of builds, you can define them inside the development and production properties of the DefinePlugin section.

The plugin does a direct text replacement, so the value given to it must include actual quotes inside of the string. You can use alternating quotes, like "'My value'", or use JSON.stringify('My value').

This is very useful to change the behavior between development and production build. For example adapting the URL prefix to an API. This is why we have predefined the constant PRODUCTION in baumeister.json.

You may take a look at the official webpack DefinePlugin docs.

Automatically load modules instead of requiring / importing them

The ProvidePlugin section is an object where the value equals the module name and the key represents the property name of the window object the module gets mapped to. See the official webpack ProvidePlugin docs for further information.

Build Workflow and npm scripts

Once you complete the setup, you'll be able to run various npm scripts from the command line. The main scripts needed for developing and building your project are listed below.

Command Description
npm start Builds for development, starts a webserver, watches files for changes, rebuilds incrementally and reloads your browser.
npm test Lints your JavaScript files and runs unit tests via the Jest CLI.
npm run test:watch Runs unit test with Jests watch option.
npm run build Builds for production to dist directory.
npm run build:serve Starts a static fileserver serving the dist directory.
npm run build:analyze Starts »webpack bundle analyzer« to visualize size of webpack output files

🔥 Tip:
There a lot more scripts defined in the package.json, but most of the other ones are used to combine scripts. Therefore we have set up an interactive CLI menu to list and run the most importants npm scripts via:

$ npm run tasks

Running those scripts will create a bunch of directories and files which aren’t under version control. Do not be concerned if you see these resources:

myProject
├──.metalsmith-build                → Compiled handlebars sources
├── coverage                        → Test coverage reports
├── dist                            → Contains the files ready for production
│   ├── app
│   └── assets
│   └── **.html
├── node_modules                    → Dependencies installed by npm
├── server                          → Contains the files for the development server
│   ├── app
│   └── assets
│   └── **.html
├── .eslintcache
├── .webpack-assets.json            → Contains bundled file names
└── .webpack-stats.json             → Contains bundle information

Setting up your Editor

We strongly advise installing an EditorConfig plugin and taking a look at the .editorconfig file in the root of this project.

Writing Markup (static sites vs. single page apps)

Baumeister acts like a static site generator by default. Using handlebars we can simplify our templates and avoid markup duplications by using a combination of pages, layouts and partials.

This is optional

Using Handlebars instead of plain HTML is fully optional and will probably suit your needs if you use Baumeister for creating a static site. If you are developing a single page application instead it would be a good idea to turn off handlebars compiling, place an index.html file in the /src directory, and store additional templates in /src/app.

In this case you have to switch off Handlebars compiling in baumeister.json:

/**
 * Boolean flag to set when using handlebars instead of plain HTML files in `src`.
 */
"useHandlebars": false

Please note:
We have additional guides for setting up Baumeister to be used with React and other single page applications libraries/frameworks in the Baumeister Wiki. The Baumeister Yeoman Generator will handle the adaptions for you if you choose to create a single page application.

Using handlebars

It’s super easy to use even if you've never used Handlebars before.

Here are some powerful things you can do with Handlebars:

Let’s dive into it by demonstrating a basic example. Imagine that we have a simplified file/folder structure like the following in our project:

src
├── index.hbs              → A page
├── anotherPage.hbs        → Another page
└── handlebars
    ├── helpers            → Place to store custom handlebars helpers (usage optional)
    │   └── add-year.js
    ├── layouts            → Place to store our layouts
    │   └── default.hbs    → Our default layout
    └── partials           → Place to store our partials (usage optional)
        └── footer.hbs

As you can see, our pages are stored in the root of the project and are rendered as html pages with a little help from Handlebars.

Let’s take a look at the content of our files.

Custom helper

Content of src/handlebars/helpers/add-year.js:

/**
 * Adds the current year to a string. Divides given string and year by a space.
 * @example:
 * {{addYear '©'}} --> © 2017
 *
 */
function addYear(s) {
	return s + ' ' + new Date().getFullYear();
}

module.exports = addYear;

Partial

Content of src/handlebars/partials/footer.hbs:

<footer>
	{{addYear '©'}} MyCompany
</footer>

Page

Content of src/index.hbs:

---
title: My page title
---
<h1>My page</h1>

<p>My content</p>

{{> footer }}

Layout file

content of src/handlebars/layouts/default.hbs:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>My Project{{#if page.title}} - {{page.title}}{{/if}}</title>
	<link rel="stylesheet" href="">
</head>
<body>
 {{{contents}}}
</body>
</html>

Rendered Result

This combination will render to one html file.

Content of index.html:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>My Project - My page title</title>
		<link rel="stylesheet" href="" />
	</head>
	<body>
		<h1>My page</h1>

		<p>My content</p>

		<footer>
			© 2017 MyCompany
		</footer>
	</body>
</html>

So the layout file is wrapped around the pages by replacing the {{{contents}}} placeholder with the pages content.

As you can see you can enrich your pages with data via so called frontmatters:

---
title: My page title
---

Frontmatters are basically a key/value storage you can access within your layouts, pages and partials via Handlebars. This empowers you to do things like handling active states of your navigation and much more.

There is one predefined key which let you choose a different layout file in case you’re using more than one:

---
layout: myOtherTemplate.hbs
---

This would need the presence of a layout named myOtherTemplate.hbs in the layouts directory to work properly. You don’t need to define the layout within your frontmatter in case you would like to use the default layout.

File and folder structure of Sass files

This is s short version of our conventions when it comes to create bootstrap themes. Below you’ll find the folder and file structure we are using:

src/assets/scss
├── _print.scss
├── _theme.scss
├── _variables.scss
├── index.scss
└── theme
    ├── _alerts.scss
    ├── _footer.scss
    ├── _mixins.scss
    ├── _scaffolding.scss
    └── _testResponsiveHelpers.scss

There seems to be a pretty huge amount of files for such a small project. So here we go with an explanation.

index.scss

Our main Sass file is the one which is creating our index.css file. This file just has a few imports.

// Import our variables to override Bootstraps default ones
@import './variables';

// Bootstrap Core
// --------------------------------------------------
@import '../../../node_modules/bootstrap/scss/bootstrap';

/**
 * --------------------------------------------------
 * Here begins our own CSS in the rendered CSS file.
 */

// Theme
// --------------------------------------------------
@import './theme';

// Print Styles
// --------------------------------------------------
// Use this file to reduce ink an optimize the readability and accessibility of the pages.
// @import "./print";

////////// Do NOT insert style-definitions here! //////////

_theme.scss

We use this file to import the modules/files which defines the actual theme. You could also use this to write down your styles and omit using separate files in the corresponding folder theme. But we recommend not doing that. See content of _theme.scss:

// Override and extend Bootstrap stuff
// --------------------------------------------------
// Files, classes, mixins etc.
@import 'theme/mixins';
@import 'theme/scaffolding';
@import 'theme/alerts';

// Own modules
// --------------------------------------------------
// @import "theme/testResponsiveHelpers"; // debug
@import 'theme/footer';

// Important note //
// You could also use this file to insert theme related style definitions
// directly within this file. But we recommend keeping your Sass code in
// separate files like the examples above when you exceed a few hundred lines
// of code. Otherwise it will definitely have a negative impact on
// maintainability.

Theme folder

This folder holds the modules needed by the theme. The skeleton of such a module looks like the following.

//
// Component name
// --------------------------------------------------
// Short component description

.component-name {
	// Local variables
	//
	// Which are meant to be used only in this module. »Global« variables are stored
	// in /src/assets/scss/_variables.scss

	// Local mixins
	//
	// Which are meant to be used only in this module. »Global« mixins are stored
	// in /src/assets/scss/theme/_mixins.scss

	// Styles
	//
}

See _footer.sass for a »real life« example.

There are three files which differ from regular components. Please have a look at comments within the following files to get an idea how to handle them:

  • _variables.scss Used to override bootstrap variables. Make sure to read the comments which describe how to handle this file which can save you lots of time when it comes to a Bootstrap update.
  • _mixins.scss Holds additional global mixins which are meant to be used across modules.
  • _scaffolding.scss Used to define the most generic html elements.

Using external libraries

Let’s assume you'd like to add some fanciness to your form select fields. This could be accomplished with Select2.

This is how you get the files into your /node_modules directory and define the dependency in the package.json file.

cd path/to/your/checkout/of/baumeister
npm search select2

This leads to something like:

NAME                      | DESCRIPTION          | AUTHOR          | DATE       | VERSION  | KEYWORDS
select2                   | Select2 is a jQuery… | =chrisjbaik…    | 2016-05-27 |          | select autocomplete typeahead dropdown multiselect tag tagging
Select2                   | Select2 is a jQuery… | =syastrebov     | 2016-08-05 |          | select autocomplete typeahead dropdown multiselect tag tagging
ember-power-select        | The extensible…      | =cibernox       | 2017-03-17 |          | ember-addon select select2 selectize dropdown
select2-bootstrap-css     | Simple CSS to make…  | =fk             | 2015-02-03 |          | bootstrap select2 css
vue-select                | A native Vue.js…     | =sagalbot       | 2017-03-12 |          |

where the Name is your key for installation. In our use case you would do:

npm install --save select2

which will:

  • download the latest and greatest version to your node_modules directory
  • add "select2": "^4.0.6" to your package.json

Using and bundling JavaScript dependencies

// Import select2
import 'select2';

$(() => {
	// Using select2
	$('.single-select').select2();
});

Importing the library into your JavaScript will automatically add the needed sources to the vendor.bundle.js file.

The bundled vendor JavaScript is stored in the app directory during the build process:

myProject
└── dist
    └── app
        └── vendor.694dbf332f7953c4041b.bundle.js

Bundling CSS from dependencies

If a used library ships its own CSS you have to include the paths to the files you like to bundle in the vendor.bundleCSS section of your baumeister.json to add the CSS to the vendor.bundle.css file. Please note that glob pattern matching is supported over here.

"vendor": {
    "bundleCSS": [
      "select2/dist/css/select2.css",
      "select2-bootstrap-css/select2-bootstrap.css"
    ],
    "includeStaticFiles": []
  }

The bundled CSS is stored in the css directory during the build process:

myProject
└── dist
    └── assets
        └── css
            └──vendor.694dbf332f7953c4041b.bundle.css

Including static files from dependencies

Sometimes you need to copy static files from an npm package to your project. This may be fonts or JavaScript files you need to include via separate <script> tags. To handle that you have to include the files in the vendor.includeStaticFiles section of your baumeister.json. Please note that glob pattern matching is supported over here.

"includeStaticFiles": [
  "font-awesome/fonts/**"
]

These files are stored in the vendor directory during the build process:

myProject
└── dist
    └── assets
        └── vendor
            └── font-awesome
                └── fonts
                    ├── fontawesome-webfont.eot
                    ├── fontawesome-webfont.svg
                    ├── fontawesome-webfont.ttf
                    ├── fontawesome-webfont.woff
                    └── fontawesome-webfont.woff2

Changing versions of dependencies

You can change the version of the dependencies by editing the package.json file within the root directory of the project by hand.

"dependencies": {
  "bootstrap": "^4.0.0",
  "core-js": "^2.5.3",
  "jquery": "^3.2.1",
  "popper.js": "^1.12.9",
}

The version numbers describe semver ranges where the caret ^ means: Install the latest version including minor-releases.

So ^4.0.0 installs the latest 4.x.x release which is version v4.0.0 in case of Bootstrap right now. So Bootstrap 4.0.1 as well as jQuery 4.1.0 will be fetched as soon as it is released when you call npm update or npm install. But npm won’t install Bootstrap 5.x.x or later.

Check http://semver.org/ for more information about »Semantic Versioning« or check the npm semver calculator to explore with semver ranges.

Updating beyond defined semver ranges

There are multiple ways to get newer versions than defined via the semver ranges in your package.json

Updating single dependencies via CLI

You can use npm to update single dependencies and persist changes to your package.json

For example:

npm install --save bootstrap@latest
Updating multiple dependencies at once

We recommend using a command line tool like »npm-check-update« to update multiple dependencies at once.

Adding polyfills

The file src/app/base/polyfills.js is prepared to dynamically import polyfills you might need depending on your use of modern JavaScript language, features and your target browsers. This way the polyfills are lazy loaded only in case the used browser actually needs them.

Just import the ones you need for the browsers you are targeting.

The only polyfill activated by default is a Promises polyfill which is needed for lazy loading polyfills in Internet Explorer.

Unit tests

We use Jest, for running unit tests and generating test coverage reports. See config in property jest in package.json.

Just type the following to run all tests once:

npm test

You can watch changes and run tests automatically with:

npm run test:watch

This comes in handy since it’s blazingly fast. It only run tests related to changed files per default but has an interactive mode which enables you to run all if needed.

For those who are new to Jest

Writing tests with Jest feels pretty much the same as writing tests with Mocha/Chai|Jasmine. Just look at our small dummy test in src/app/__tests__.

Placing tests in __tests__ directories is a default feature from Jest. You can adjust the name of your tests-directory with the testDirectoryName configuration option.

The most important things to know:

You are not forced to use Jests assertions. You can alternatively use assert by just requiring it or installing and using Chai.

We strongly recommend checking the docs to dive deeper and read for instance how Jest can help you with mocking.

Configuring linters

Below you’ll find information on how to adapt the rules in case they don’t fit your preferences.

ESLint (JavaScript)

We are currently using eslint-config-baumeister which is based on eslint-config-xo, eslint-plugin-unicorn, eslint-plugin-security, eslint-plugin-import, eslint-plugin-filenames with a few adaptions.

Feel free to deactivate or change the rules according to your needs here:

.eslintrc.json

See Configuring ESLint if you need to know more.

stylelint (Sass)

We are using stylelint-config-standard as presets but have adapted a few rules within:

.stylelintrc.json

See stylelint rules in case you want to get the details of these rules and the stylelint user guide to see how to configure stylelint (e.g. how to turn of rules).

Web performance optimization

There are a few things that you don’t have to worry about because Baumeister has already set them up to deliver the best possible optimizations while being safe to use (eg. image optimization and tree shaking).

Besides that, you might want to tweak settings to get an even better performance.

Deleting unused CSS

We are using PurifyCSS to remove unused selectors from your CSS. This is fully optional and is turned off by default.

To activate PurifyCSS set the usePurifyCSS option in within baumeister.json to true.

In addition you can define a PurifyCSS whitelist defining an array of selectors that should not be removed.

For example. ["button-active", "*modal*"] will leave any selector that includes modal in it and selectors that match button-active. The asterisks act like a wildcard, so wrapping a string with *, leaves all selectors that include it.

Alternative: selective imports

You could also import just the CSS from Bootstrap that you actually need in your project in src/assets/scss/index.scss. But you won‘t get your CSS bundle size that small in comparison to PurifyCSS.

Make use of long-term caching

You should set far-future Cache-Control and Expires headers (see Apache settings and settings for other web servers). This ensures resources are cached for a specified time period (usually a year or more). So the browser will only hit the network if the file name changes (or if a year passes or if the user manually erases their browser cache).

By default we are revisioning the bundled assets with adding a content based hash to the filenames for the production build. So for instance the file app.bundle.js will be renamed to something like app.6c38e655f70a4f9e3d26.bundle.js. The filename will change when the file content changes which will force the browser to re-download changed files instead of serving them from the cache.

We’ve set up webpack to store the webpack runtime in an separate file to improve the cacheability of the vendor bundle (otherwise the hash of vendor.js would change even with changes to app.js).

Deactivate cache busting

You can disable hash based file name revving by setting the cacheBusting property within baumeister.json to false.

Selective JavaScript imports

Some libraries, such as react-bootstrap and lodash, are rather large and pulling in the entire module just to use a few pieces would cause unnecessary bloat to your JavaScript vendor bundle.

babel-plugin-transform-imports can be used to add only what you need to your bundle. It automatically transforms member style imports such as:

import { Row, Grid as MyGrid } from 'react-bootstrap';
import { merge } from 'lodash';

into default style imports:

import Row from 'react-bootstrap/lib/Row';
import MyGrid from 'react-bootstrap/lib/Grid';
import merge from 'lodash/merge';

Check the packages page to read about the why.

Baumeister has already set up the plugin for lodash, reactstrap, react-bootstrap and react-router just in case you will use them. See src/app/.babelrc to add aditional libraries.

Automatic code formatting

We are using prettier to format JavaScript, JSON and SCSS files automatically before you commit your files to Git via a pre-commit hook.

The prettier settings are defined in .prettierrc in the project root. In case prettier is to opinated for you or you don’t want Prettier to change your files without the chance to review the changes you just have to delete the pre-commit hook with in the package.json:

"husky": {
  "hooks": {
    "post-merge": "npm install",
    "pre-commit": "lint-staged"
  }
}

But we totally recommend you to give this workflow a chance, because it’s just one more thing you don’t have to care about.

Adding banners

Adding banners on top of the production bundles is fully optional and is turned off by default.

It can be enabled with setting the generateBanners property within baumeister.json to true.

/**
 * Flag for generating banners on on top of dist files (CSS & JS).
 */
"generateBanners": true

If enabled it will place the following banners in the bundled CSS and JS files:

/*!
 * <%= pkgJson.title %> - v<%= pkgJson.version %>
 * <%= pkgJson.author.email %>
 * Copyright ©<%= year %> <%= pkgJson.author.name %>
 * <%= fullDate %>
 */

Release Workflow

We provide the following npm scripts to automate releases:

npm run release:patch
npm run release:minor
npm run release:major

See http://semver.org for details of when to choose which release type.

As long as your git commit messages are conventional and accurate, you no longer need to specify the semver type. You can just use the following instead:

npm run release

This script can also be used to define pre-releases by adding the optional flags like npm run release -- --prerelease beta. See Release as a pre-release for further information.

All release scripts will:

  • bump the version number in package.json
  • generate a changelog
  • commit changes
  • create a Git tag

Examples

# Bump version from 3.1.2 to 4.0.0
npm run release:major

# Bump version from 3.1.2 to 3.2.0
npm run release:minor

# Bump version from 3.1.2 to 3.1.3
npm run release:patch

# Bump version from 3.1.2 to 4.0.0-beta.0
npm run release -- --prerelease beta --release-as major

# Bump prerelease version eg. from 4.0.0-beta.0 to 4.0.0-beta.1
npm run release -- --prerelease

Changelog creation

The changelog is stored in the file CHANGELOG.MD in the project root. Every release updates this file.

We are using »conventional changelog« to get relevant changes out of the git commit history and group them nicely.

You should write your commit messages with these conventions in mind.

See the last commits of Baumeister for some real life commit messages.

Short summary of the conventions

Example commit message:

fix(uglify): Remove console output and debugger statements

Consists of:

type(scope): subject
Types

Types are used to group commits in the changelog. Possible types which are rendered in the changelog are: feat, fix and perf.

There are additional ones which you can use. But these are only rendered if they introduce a breaking change: docs, chore, style, refactor, and test.

Scope

The scope is optional and you can choose from whatever you want. The scope is used as another grouping element below the type.

You can skip the parentheses if you don’t want to use Scope:

style: Fix linting errors
Subject

The subject contains a succinct description of the change:

  • use the imperative, present tense: "change" not "changed" nor "changes"
  • capitalize first letter
  • don't add a dot (.) at the end
Additional Info, Breaking changes and issue references

These are defined in the body of the commit message.

Example:

feat(build): Replace Gulp with webpack and npm scripts
<BLANK LINE>
Closes #225
BREAKING CHANGE: Gulp tasks aren’t available any longer.
But there are equivalent npm scripts.
List the available scripts with `npx nls`

The body can include the motivation for the change and contrast this with previous behavior.

Plus it should contain any information about Breaking Changes and is also the place to reference GitHub issues that this commit Closes.

Breaking Changes should start with the word BREAKING CHANGE: with a space or two newlines. The rest of the commit message is then used for this.

Generated Changelog

This is how a changelog based on this conventions is rendered: https://github.com/micromata/Baumeister/blob/master/CHANGELOG.md

Contributing to this project

Anyone and everyone is welcome to contribute. Please take a moment to review our Code of Conduct as well as our guidelines for contributing.

License

Please be aware of the licenses of the components we use in this project. Everything else that has been developed by the contributions to this project is under MIT License.

baumeister's People

Contributors

hthole avatar krnlde avatar mischah avatar nicolaisueper avatar talater avatar zfais74 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

baumeister's Issues

Bring back cachebusting (for js and css on production html files)

We had that once upon a time for our dev files. Which caused some trouble and actually wasn’t needed, because you should simply disable chaching within the devtools (when they are open).

But how about adding this to html files in the distdirectory?
Need to figure that out …

Loading "autoprefixer.js" tasks...ERROR >> Error: Cannot find module 'browserslist'

In fact, I get a whole bunch of errors when I run grunt tasks and the process aborts.

 ➜  grunt tasks
Loading "autoprefixer.js" tasks...ERROR
>> Error: Cannot find module 'browserslist'
Loading "bootlint.js" tasks...ERROR
>> Error: Cannot find module 'cheerio'
Loading "plato.js" tasks...ERROR
>> Error: Cannot find module 'plato'

Running "availabletasks:tasks" (availabletasks) task
Warning: Cannot set property 'info' of undefined Use --force to continue.

Aborted due to warnings.


Execution Time (2015-03-12 09:01:52 UTC)
loading tasks         61ms  ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 42%
availabletasks:tasks  83ms  ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 57%
Total 145ms

Any ideas?

I installed Bootstrap Kickstart with yo bootstrap-kickstart

The imagemin task »doesn’t« work

Oops 🙈

Reason:

Could be fixed with deleting the following line:
https://github.com/micromata/bootstrap-kickstart/blob/master/Gruntfile.js#L303

Thanks @uschmidt for reporting 😘

Bump version after linting in release tasks

It might happen that you encounter linting errors (htmllint, bootlint, jshint) etc. while running one of the release tasks. Which will lead to creating a Git tag without »finishing« the release.

You could consider calling that an edge case, because it will only happen, if you don’t use the watch task during development. But I guess it’s worth checking how to get rid of these potential problems.

Please note:
It's not fixed by just reordering the tasks within the release-tasks like in the following example

Before:

['bump-only:patch', 'build', 'clean:js', 'changelog', 'bump-commit', 'compress']

After:

['build', 'clean:js', 'bump-only:patch', 'changelog', 'bump-commit', 'compress']

Because that will mess up the releases:

  • The »old« version number will be placed within the comment banners of CSS and JS files
  • Surprisingly the minified CSS wasn’t updated within the release after that attempt (might be caused by something else. It was late 😄)

Needs further investigation …

Improve production build

  • Delete non minified CSS from Production build
  • Merge JavaScript
  • Define Bootstrap Modules for Production build
  • Add version to »dist« directory?

Get rid separate minified JS files in `dist`

Until now we create minified versions of each and every JS file beside built.min.js.
Therefore dist/assets/js ends up being packed with files like:

base.min.js
built.min.js
moduleFoo.min.js
moduleBar.min.js
moduleFooBar.min.js

I don’t see any need for these files (besides built.min.js of course ☺️ )

@krnlde Do you agree with getting rid of them?

Reduce bundle file-size

Using browserify the file size of the bundle can be dramatically reduced by declaring frontend-dependencies like »bootstrap« or »jquery« as external. I think the already modified variant is used in this case. Maybe we should generally declare all dependencies as externally!? Maybe by parsing the dependencies property of the package.json? The other benefit is that the bundling will be faster, because external dependencies aka »vendors« are only bundled once.

Make use of includes for repeating elements like header, footer etc.

Example:
You have a project with 10 pages and every page shares elements like footer, header etc.
So If you want to change something in the footer you have to adapt the change in all of the 10 pages.

To avoid this you could make use of includes. This feature is provided by grunt-processhtml. We already use this task in the default bootstrap kickstart but we don’t use the include feature by default.

I think that would be a useful addition although it will increase complexity of the gruntfile because we need an additional directory (and corresponding tasks) to store the builded html to make the server task work.

Another negative connotation: The line numbers of the markup linters (htmllint and bootlint) won’t fit any longer, because we need to lint the combined files (with rendered includes) 😞

Need another module system for JS modules

… and a module loader instead of using the revealing module pattern relying on the global scope (even with using a namespace to prevent polluting the global scope).

Going to take a closer look at:

  • browserify for using CommonJS modules
  • SystemJS or ES6 Module Loader polyfill for using ES6 modules

Any thoughts on that @krnlde?

Does splitting up the Gruntfile increases maintainability?

Should we split that huge monster in separate files handling one task each.

See the following for inspiration:

Update
I’m not sure wether that splitting up the gruntfile really increases maintainibility. Is it easier to browse through multiple files than scroll through one? See Discussion over here: yeoman/generator-webapp#245

Feedback appreciated :octocat:

Replace Grunt with with Gulp

First of all:
I don’t want to start a flamewar »Gulp« vs »Grunt« vs »npm run scripts« over here 🙈 🙉 🙊

While I would vote for getting rid of a task runner for small projects and use npm run scripts instead I still see the need of a task runner for Bootstrap Kickstart.

Second:
I don’t feel the urgent need to ditch Grunt because things still work, but there might be a few reasons to dump Grunt in favor of Gulp.

Gulp Pros:

  • Performance – faster builds and running watch tasks during development
  • Better maintained – Grunt seems to be stuck in development. Last Release was in Mai 2014

While I don’t care that much that Gulp Gulp is the most popular »build script solution« it might have a psychological aspects for potential Bootstrap Kickstart users. Because I see issues raising in other open source tools where people ask about switching to Gulp.

Grunt Pros:

  • It just works – We dont have to rewrite the whole workflow
  • It could be easier to configure for people whose daily business isn’t writing JavaScript. (Configuration over code)

So how this is going to happen?

First I like to implement a small Gulp proof of concept including just a few tasks to measure the performance advantage over Grunt. Because I would like to see if the rewrite is worth the bother.

I would love to get the advantages which come with Gulp 4. But I don’t want to wait until it’s shipped (no release date in sight). I hope it won’t take long. So I think I could start with the alpha version of Gulp4 even if there is a risk that things might change.


Relates to #42

Rename task `grunt server`

Rename grunt server to grunt serve. Former seems to be something like a »de facto standard«.

We could alias the old name to the new to avoid confusion 😉

Include JS Unit Tests

Add unit test boilerplate with the following stack:

  • mocha (grunt-mocha-phantomjs vs. grunt-karma / karma-mocha)
  • chai (using bdd 'expect' style)
  • blanket.js for coverage

Update variables.less from latest bootstrap

There are new variables like the following which are pretty useful 😗

// Allows for customizing button radius independently from global border radius
@btn-border-radius-base:         @border-radius-base;
@btn-border-radius-large:        @border-radius-large;
@btn-border-radius-small:        @border-radius-small;

error Expected linebreaks to be 'LF' but found 'CRLF'

consoleLog.txt

Hi,
consoleLog File is attached.
It seems to be a problem with:

http://eslint.org/docs/rules/linebreak-style

under Windows.

...
66:12 error Expected linebreaks to be 'LF' but found 'CRLF' linebreak-style
67:1 error Expected linebreaks to be 'LF' but found 'CRLF' linebreak-style
68:4 error Expected linebreaks to be 'LF' but found 'CRLF' linebreak-style
69:50 error Expected linebreaks to be 'LF' but found 'CRLF' linebreak-style
70:10 error Expected linebreaks to be 'LF' but found 'CRLF' linebreak-style
71:4 error Expected linebreaks to be 'LF' but found 'CRLF' linebreak-style
72:16 error Expected linebreaks to be 'LF' but found 'CRLF' linebreak-style
73:15 error Expected linebreaks to be 'LF' but found 'CRLF' linebreak-style
74:1 error Expected linebreaks to be 'LF' but found 'CRLF' linebreak-style
75:55 error Expected linebreaks to be 'LF' but found 'CRLF' linebreak-style
76:4 error Expected linebreaks to be 'LF' but found 'CRLF' linebreak-style

? 989 problems (989 errors, 0 warnings)

Warning: Task "eslint:check" failed. Use --force to continue.

Aborted due to warnings.
...

Add `dist` directory to version control?

Some people are doing this to have a »running version« immediately after checkout.

Doesn’t make much sense for the »kickstart« itself. But for the projects based on the »kickstart« it could.

Feedback appreciated :octocat:

Extend default options of uncss task

To prevent that UnCSS is killing bootstrap animations 😁

Something like:

uncss: {
  options: {
    ignoreSheets: [/fonts.googleapis/],
    timeout: 2000,
    ignore: [
      /\w\.in/,
      /(#|\.)navbar(\-[a-zA-Z]+)?/,
      /(#|\.)modal(\-[a-zA-Z]+)?/,
      /(#|\.)dropdown(\-[a-zA-Z]+)?/,
      /(#|\.)carousel(\-[a-zA-Z]+)?/,
      /(#|\.)(open)/,
      '.fade',
      '.collapse',
      '.collapsing',
      '.in'
    ]
  },
  dist: {
    src: '<%= config.server %>/*.html',
    dest: 'temp/index.css'
  }
},

timeout: 2000 ensures that all classes that should be added on onDOMContentLoaded are applied.

Release tasks should commit all changed files

So:

bump: {
  options: {
    files: ['package.json', 'bower.json'],
    updateConfigs: ['pkg'],
    commitMessage: 'Release v%VERSION%',
    commitFiles: ['package.json', 'bower.json', 'CHANGELOG.md'],
    tagName: '%VERSION%',
    tagMessage: 'Release v%VERSION%',
    push: false,
  }
}

should be changed into:

bump: {
  options: {
    files: ['package.json', 'bower.json'],
    updateConfigs: ['pkg'],
    commitMessage: 'Release v%VERSION%',
    commitFiles: ['-a'],
    tagName: '%VERSION%',
    tagMessage: 'Release v%VERSION%',
    push: false,
  }
}

In addition it would be useful if new (and untracked) files in the dist directory are added to version control first.

Add files automagically to version control in release tasks

Related to #29

If you have new files in dist since last release the won’t be commited with the release because they are unknown for Git.

Which leads to »refinish« a release by:

  1. Deleting the Git tag pointing to your release tag
  2. Adding the unknown files to Git
  3. git commit --amend
  4. Creating a knew tag pointing to the »new« release commit.

Make the kickstarter fast again for it's main purpose: development

I experience huge loads each time I'm downloading, installing, starting and running the kickstarter project. Most of the tasks that run for development aren't per se necessary at the beginning of a project. Sure we need reports, sure we need imagemin and all that sorts of stuff. But, as the name quotes, a kick-ass start would be the biggest gainer :)

What do you think @mischah ?

Error on build process

I get this error and i dont know whats wrong?
I dont change anything.

Running "cssmin:bower" (cssmin) task
Warning: Path must be a string. Received undefined Use --force to continue.

Error calling .postinstall.js script in package.json on Windows 7

Calling the .postinstall.js script from node install produces an error on Windows 7 systems.
Because Windows doesn't recognize the shebang line in scripts and handles binaries with file endings associated programs. In this case (.js) with the Windows Scripting Host.

replacing the script configuration with:

"scripts": {
    "postinstall": "chmod u+x .postinstall.js && node ./.postinstall.js"
  }

it works again. The important thing here is adding 'node' before .postinstall.js, telling Windows explicit to use node.js to run the script.

Unfortunately i cannot confirm if this change breaks this on Linux or Mac Os systems.

Also read this article: Writing cross-platform Node.js scroll down until "Scripts in package.json", there is the problem also specified with my solution.

Hardcoded Copyright in Gruntfile.js

The copyright to Micromata is hardcoded in the Gruntfile.js although the pkg.name variable is used to print out the package name.

Here is an example:

banner: '/*! <%= pkg.title %> - v<%= pkg.version %>\n' +
         ' * [email protected]\n' +
         ' * Copyright ©<%= grunt.template.today("yyyy") %> Micromata GmbH\n' +
         ' * <%= grunt.template.today("yyyy-mm-dd") %>\n' +
         ' */',

It would be better to use the pkg.author.email variable or anything comparable to this.

Switch to ESLint

I think the switch to ESLint makes more sense than adding JSCS.

I guess @krnlde agrees 😊

… but there is one thing I’m still considering. Should we:

I would prefer the latter option because of simplicity. I personally prefer the same code styles as @sindresorhus and believe that he will maintain a trustworthy config over here: https://github.com/sindresorhus/eslint-config-xo/blob/master/index.js

@krnlde Are you with me?

Remove comments within production *.html files in dist directory

Comments like the following doesn’t need to be in the production html files:

<!--
  Replace "no-js" class with "js" in case JavaScript is available.
  You can delete this when you feel the need to make use of modernizr.
-->

@krnlde @mfroehner
I think this is a no-brainer. Thanks for the suggestion 😊

But what to you think about going one step further and use HTMLMinifier to get rid of comments as well as whitespaces and line breaks?

Pros:

  • Save a few kilobytes

Cons:

  • Inspecting the processed html files within an editor is useless
    • In the browser view in the Dev Tools aren’t affected.
  • Might cause problems in oldIEs because I remember browser bugs which are caused by whitespace
    • But as long as I know several bugs are caused by whitespace and can be »fixed« by removing whitespace.

What’s your opinion on that?

Integrate `git merge` → `git push` into releases tasks?

Should we intergrate the following into the release tasks?

  • Merge to master?
  • Push to origin?

Now

grunt.registerTask('releasePatch',
  ['bump-only:patch', 'build', 'changelog', 'bump-commit', 'compress']
);

Then

grunt.registerTask('releasePatch',
  ['bump-only:patch', 'build', 'changelog', 'bump-commit', 'compress', 'git:merge', 'git:push']
);

Could be accomplished with https://github.com/rubenv/grunt-git

Or is this taken to far?
I’m not sure, if I like to merge and push something I haven’t reviewed.

Feedback appreciated :octocat:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.