Anything you put in the copy directory gets copied as-is into the dist directory.
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | module.exports = function (config) {
2 | config.set({
3 | frameworks: ['jasmine', 'karma-typescript'],
4 | files: [
5 | { pattern: 'src/**/*.ts' }
6 | ],
7 | preprocessors: {
8 | '**/*.ts': ['karma-typescript']
9 | },
10 | reporters: ['progress', 'karma-typescript', 'kjhtml'],
11 | htmlReporter: {
12 | outputDir: 'coverage/karma_html', // where to put the reports
13 | templatePath: null, // set if you moved jasmine_template.html
14 | focusOnFailures: true, // reports show failures on start
15 | namedFiles: false, // name files instead of creating sub-directories
16 | pageTitle: null, // page title for reports; browser info by default
17 | urlFriendlyName: false, // simply replaces spaces with _ for files/dirs
18 | reportName: 'report-summary-filename', // report summary filename; browser info by default
19 |
20 | // experimental
21 | preserveDescribeNesting: false, // folded suites stay folded
22 | foldAll: false, // reports start folded (only with preserveDescribeNesting)
23 | },
24 | browsers: ['Chrome'],
25 | singleRun: false,
26 | client: {
27 | clearContext: false
28 | }
29 | });
30 | };
31 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | // Plugins
2 | import { terser } from 'rollup-plugin-terser';
3 | import { nodeResolve } from '@rollup/plugin-node-resolve';
4 | import pkg from './package.json';
5 |
6 |
7 | // Configs
8 | var configs = {
9 | files: ['main.js', 'detects.js', 'another-file.js'], // package root files
10 | formats: ['es'], // ['iife', 'es', 'amd', 'cjs'],
11 | default: 'es',
12 | pathIn: 'compiledjs',
13 | pathOut: 'dist/js',
14 | minify: true,
15 | sourceMap: false
16 | };
17 |
18 | // Banner
19 | var banner = `/*! ${pkg.name} v${pkg.version} | (c) ${new Date().getFullYear()} ${pkg.author.name} | ${pkg.license} License | ${pkg.repository.url} */`;
20 |
21 | var createOutput = function (filename, minify) {
22 | return configs.formats.map(function (format) {
23 | var output = {
24 | file: `${configs.pathOut}/${filename}${format === configs.default ? '' : `.${format}`}${minify ? '.min' : ''}.js`,
25 | format: format,
26 | banner: banner
27 | };
28 | if (format === configs.default) {
29 | output.name = pkg.name;
30 | }
31 | if (minify) {
32 | output.plugins = [terser()];
33 | }
34 |
35 | output.sourcemap = configs.sourceMap
36 |
37 | return output;
38 | });
39 | };
40 |
41 | /**
42 | * Create output formats
43 | * @param {String} filename The filename
44 | * @return {Array} The outputs array
45 | */
46 | var createOutputs = function (filename) {
47 |
48 | // Create base outputs
49 | var outputs = createOutput(filename);
50 |
51 | // If not minifying, return outputs
52 | if (!configs.minify) return outputs;
53 |
54 | // Otherwise, ceate second set of outputs
55 | var outputsMin = createOutput(filename, configs.minify);
56 |
57 | // Merge and return the two arrays
58 | return outputs.concat(outputsMin);
59 |
60 | };
61 |
62 | /**
63 | * Create export object
64 | * @return {Array} The export object
65 | */
66 | var createExport = function (file) {
67 | return configs.files.map(function (file) {
68 | var filename = file.replace('.js', '');
69 | return {
70 | input: `${configs.pathIn}/${file}`,
71 | output: createOutputs(filename),
72 | plugins: [nodeResolve()],
73 | };
74 | });
75 | };
76 |
77 | export default createExport();
78 |
--------------------------------------------------------------------------------
/sass.js:
--------------------------------------------------------------------------------
1 | var sass = require('sass');
2 | var fs = require('fs');
3 | var pkg = require('./package.json');
4 |
5 |
6 | // Configs
7 | var configs = {
8 | files: ['main.scss'],
9 | pathIn: 'src/scss',
10 | pathOut: 'dist/css',
11 | indentType: 'tab',
12 | indentWidth: 1,
13 | minify: true,
14 | sourceMap: false
15 | };
16 |
17 | // Banner
18 | var banner = `/*! ${pkg.name} v${pkg.version} | (c) ${new Date().getFullYear()} ${pkg.author.name} | ${pkg.license} License | ${pkg.repository.url} */`;
19 |
20 | var getOptions = function (file, filename, minify) {
21 | return {
22 | file: `${configs.pathIn}/${file}`,
23 | outFile: `${configs.pathOut}/${filename}`,
24 | sourceMap: configs.sourceMap,
25 | sourceMapContents: configs.sourceMap,
26 | indentType: configs.indentType,
27 | indentWidth: configs.indentWidth,
28 | outputStyle: minify ? 'compressed' : 'expanded'
29 | };
30 | };
31 |
32 | var writeFile = function (pathOut, fileName, fileData, printBanner = true) {
33 | // Create the directory path
34 | fs.mkdir(pathOut, { recursive: true }, function (err) {
35 | // If there's an error, throw it
36 | if (err) throw err;
37 |
38 | // Write the file to the path
39 | fs.writeFile(`${pathOut}/${fileName}`, fileData, function (err) {
40 | if (err) throw err;
41 |
42 | var data = fs.readFileSync(`${pathOut}/${fileName}`);
43 | var fd = fs.openSync(`${pathOut}/${fileName}`, 'w+');
44 | var insert = printBanner ? new Buffer.from(banner + '\n') : '';
45 | fs.writeSync(fd, insert, 0, insert.length, 0);
46 | fs.writeSync(fd, data, 0, data.length, insert.length);
47 | fs.close(fd, function (err) {
48 | if (err) throw err;
49 | console.log(`Compiled ${pathOut}/${fileName}`);
50 | })
51 | })
52 | })
53 | }
54 |
55 | var parseSass = function (file, minify) {
56 | var filename = `${file.slice(0, file.length - 5)}${minify ? '.min' : ''}.css`;
57 | sass.render(getOptions(file, filename, minify), function (err, result) {
58 |
59 | // If there's an error, throw it
60 | if (err) throw err;
61 |
62 | // Write the file
63 | writeFile(configs.pathOut, filename, result.css);
64 |
65 | if (configs.sourceMap && !configs.sourceMapEmbed) {
66 | // Write external sourcemap
67 | writeFile(configs.pathOut, filename + '.map', result.map, false);
68 | }
69 | });
70 | };
71 |
72 | configs.files.forEach(function (file) {
73 | parseSass(file);
74 | if (configs.minify) {
75 | parseSass(file, configs.minify);
76 | }
77 | });
78 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "TS-project-template",
3 | "version": "2.0.0",
4 | "description": "Simple recipes for building and compiling with the CLI.",
5 | "author": {
6 | "name": "Tom Raaff",
7 | "url": "https://github.com/TomRaaff"
8 | },
9 | "license": "MIT",
10 | "repository": {
11 | "type": "git",
12 | "url": "https://github.com/TomRaaff/TS-project-template"
13 | },
14 | "scripts": {
15 | "start": "npm-run-all -p watch server-start",
16 | "test": "node_modules/karma/bin/karma start",
17 | "clean": "recursive-delete 'dist' && recursive-delete 'compiledjs'",
18 | "ts": "tsc",
19 | "js": "rollup --config",
20 | "css": "node sass.js",
21 | "svg": "svgo -f src/svg dist/svg -r --disable=removeViewBox,removeTitle",
22 | "img": "imagemin src/img/* --out-dir=dist/img --plugin=pngquant --plugin=mozjpeg --plugin=pngcrush --plugin=zopfli",
23 | "copy": "recursive-copy 'src/copy' 'dist'",
24 | "build-dirty": "npm run ts && npm-run-all -p js css svg img copy",
25 | "build": "npm-run-all -s clean build-dirty",
26 | "watch-ts": "chokidar './src/**/*.ts' -c 'npm run ts'",
27 | "watch-css": "chokidar './src/**/*.scss' -c 'npm run css'",
28 | "watch-js": "chokidar './compiledjs/**/*.js' -c 'npm run js'",
29 | "watch-svg": "chokidar './src/**/*.svg' -c 'npm run svg'",
30 | "watch-img": "chokidar './src/img/**/*.*' -c 'npm run img'",
31 | "watch-copy": "chokidar './src/copy/**/*.*' -c 'npm run copy'",
32 | "watch": "npm-run-all -p build watch-ts watch-css watch-js watch-svg watch-img watch-copy",
33 | "server-start": "browser-sync start --files 'dist' --server 'dist'"
34 | },
35 | "devDependencies": {
36 | "@rollup/plugin-node-resolve": "^13.0.0",
37 | "@types/jasmine": "^3.7.8",
38 | "browser-sync": "^2.26.14",
39 | "chokidar-cli": "^2.1.0",
40 | "imagemin-cli": "^6.0.0",
41 | "imagemin-mozjpeg": "^8.0.0",
42 | "imagemin-pngcrush": "^6.0.0",
43 | "imagemin-pngquant": "^8.0.0",
44 | "imagemin-zopfli": "^6.0.0",
45 | "jasmine-core": "^3.8.0",
46 | "karma": "^6.3.4",
47 | "karma-chrome-launcher": "^3.1.0",
48 | "karma-jasmine": "^4.0.1",
49 | "karma-jasmine-html-reporter": "^1.6.0",
50 | "karma-typescript": "^5.5.1",
51 | "npm-run-all": "^4.1.5",
52 | "recursive-fs": "^2.1.0",
53 | "rollup": "^2.6.1",
54 | "rollup-plugin-terser": "^7.0.2",
55 | "sass": "^1.26.5",
56 | "svgo": "^1.3.2",
57 | "typescript": "^4.3.5"
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/src/copy/favicon/safari-pinned-tab.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
79 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */
4 |
5 | /* Basic Options */
6 | // "incremental": true, /* Enable incremental compilation */
7 | "module": "ES2015", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */
8 | "moduleResolution": "Node", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
9 | "lib": ["dom", "ES2020"], /* Specify library files to be included in the compilation. */
10 | // "allowJs": true, /* Allow javascript files to be compiled. */
11 | // "checkJs": true, /* Report errors in .js files. */
12 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
13 | // "declaration": true, /* Generates corresponding '.d.ts' file. */
14 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
15 | "sourceMap": true, /* Generates corresponding '.map' file. */
16 | // "outFile": "./", /* Concatenate and emit output to single file. */
17 | "outDir": "./compiledjs", /* Redirect output structure to the directory. */
18 | // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
19 | // "composite": true, /* Enable project compilation */
20 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
21 | "removeComments": true, /* Do not emit comments to output. */
22 | // "noEmit": true, /* Do not emit outputs. */
23 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */
24 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
25 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
26 |
27 | /* Strict Type-Checking Options */
28 | "strict": true, /* Enable all strict type-checking options. */
29 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
30 | // "strictNullChecks": true, /* Enable strict null checks. */
31 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */
32 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
33 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
34 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
35 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
36 |
37 | /* Additional Checks */
38 | // "noUnusedLocals": true, /* Report errors on unused locals. */
39 | // "noUnusedParameters": true, /* Report errors on unused parameters. */
40 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
41 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
42 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
43 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an 'override' modifier. */
44 | // "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */
45 |
46 | /* Module Resolution Options */
47 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
48 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
49 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
50 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
51 | // "typeRoots": [], /* List of folders to include type definitions from. */
52 | // "types": [], /* Type declaration files to be included in compilation. */
53 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
54 | "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
55 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
56 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
57 |
58 | /* Source Map Options */
59 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
60 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
61 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
62 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
63 |
64 | /* Experimental Options */
65 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
66 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
67 |
68 | /* Advanced Options */
69 | "skipLibCheck": true, /* Skip type checking of declaration files. */
70 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # TS Project Template
2 | A simple template for using NPM tasks to build and compile TypeScript, JavaScript, CSS, and image files.
3 | Based on [Chris Ferdinandi's Build Tool Boilerplate](https://github.com/cferdinandi/build-tool-boilerplate)
4 | More info on Chris' [build filosophies.](https://open.spotify.com/episode/3bfISkRGO11Srs8Ask7N1H?si=k89d4n7hSgGp-0EpYOeQQw&utm_source=copy-link&dl_branch=1&nd=1)
5 |
6 | **Install**
7 |
8 | - [Install Node.js.](http://nodejs.org/)
9 |
10 | **Quick Start**
11 |
12 | Each task has just one or two dependencies (*except for image optimization*), so I recommend deleting the ones you don't need before running `npm install`. Learn more in [the documentation](#documentation) below.
13 |
14 | 1. In bash/terminal/command line, `cd` into your project directory.
15 | 2. Run `npm install`.
16 | 3. Run `npm run build`.
17 | 4. Run `npm start` to start local development
18 |
19 |
20 | ## Documentation
21 |
22 | This is a template that you can use as a starting point for your projects.
23 |
24 | [Running Tasks](#running-tasks) · [JavaScript](#javascript) · [Sass => CSS](#sass--css) · [SVG Optimization](#svg-optimization) · [Image Optimization](#image-optimization) · [Copy Files](#copy-files) · [Clean](#clean) · [Complete Build](#complete-build) · [Watch for Changes](#watch-for-changes) · [Server](#server)
25 |
26 |
27 | ### Running Tasks
28 |
29 | The template uses the `npm run` command to run tasks. These work on macOS, Linux, and Windows systems.
30 |
31 | ```bash
32 | # Main Tasks
33 | npm start # run a localhost server that reloads when files change]
34 | npm run test # run tests
35 | npm run ts # compile ts
36 | npm run js # compile and minify
37 | npm run css # compile and minify Sass into CSS
38 | npm run svg # optimize SVGs with SVGO
39 | npm run img # optimize image files
40 | npm run copy # copy files from the src/copy directory as-is into /dist
41 | npm run clean # delete the /dist directory
42 | npm run build # run all tasks
43 | npm run watch # watch for changes and rebuild
44 |
45 | # Modular Tasks
46 | npm run watch-ts # watch for changes to the /ts directory
47 | npm run watch-js # watch for changes to the /js directory
48 | npm run watch-css # watch for changes to the /css directory
49 | npm run watch-svg # watch for changes to the /svg directory
50 | npm run watch-img # watch for changes to the /img directory
51 | npm run watch-copy # watch for changes to the /copy directory
52 | npm run build-dirty # run a new build without deleting the /dist directory
53 | npm run server-start # start a server without watching for changes
54 | ```
55 |
56 | ### Local Development
57 | use `npm run start` to build the project and start a server that reloads when file changes are detected.
58 |
59 | ### TypeScript
60 | Before any minification and bundling is done, all .ts files are first compiled and moved to the ./compiledjs folder.
61 |
62 | TypeScript files should be in the `src/ts` directory.
63 |
64 | ### JavaScript
65 |
66 | The template uses [rollup.js](https://rollupjs.org) with the [terser](https://terser.org/) plugin to parse, compile, and minify JavaScript files.
67 |
68 | ```json
69 | {
70 | "devDependencies": {
71 | "rollup": "^2.6.1",
72 | "rollup-plugin-terser": "^7.0.2"
73 | }
74 | }
75 | ```
76 |
77 | In the `rollup.config.js` file, there's a `configs` object that you can use to control what rollup.js does.
78 |
79 | ```js
80 | // Configs
81 | var configs = {
82 | name: 'MyProject', // Global namespace to use for IIFEs [optional]
83 | files: ['main.js', 'detects.js'], // The files to process
84 | formats: ['iife', 'es'], // The formats to output - will be added as a suffix to the filename (ex. main.es.js)
85 | default: 'iife', // Files with this format will not have a format suffix [optional]
86 | pathIn: 'src/js', // The source directory for your JS files
87 | pathOut: 'dist/js', // The directory to compile JS files into
88 | minify: true, // If true, a minified version will also be created with the .min suffix
89 | sourceMap: false // If true, sourcemaps are created for each processed file †
90 | };
91 | ```
92 |
93 | A banner is automatically generated from your `package.json` data.
94 |
95 | It includes the project name and version, a copyright notice with the current year and the package author name, the license type, and a link to the project repository.
96 |
97 | _If a `configs.name` property is included, that will be used. If not, the banner defaults to the `name` property in your `package.json` file._
98 |
99 | ```js
100 | // Banner
101 | var banner = `/*! ${configs.name ? configs.name : pkg.name} v${pkg.version} | (c) ${new Date().getFullYear()} ${pkg.author.name} | ${pkg.license} License | ${pkg.repository.url} */`;
102 | ```
103 |
104 | To concatentate multiple files into one, use the ES modules `import` feature.
105 |
106 | ```js
107 | // myplugin.js
108 | // This will compile into /dist/js/myplugin.js, and will include helpers.js, app.js, and event-listeners.js
109 |
110 | import * as Helpers from './helpers.js';
111 | import app from './app.js';
112 | import './event-listeners.js';
113 | ```
114 |
115 | _**Note for FireFox users:** ensure that ['Use Source Maps'](https://github.com/cferdinandi/build-tool-boilerplate/issues/7#issuecomment-811432626), and ['Show original sources'](https://github.com/cferdinandi/build-tool-boilerplate/issues/7#issuecomment-811855711) options are enabled in Developer Tools._
116 |
117 | ### Sass => CSS
118 |
119 | The template uses the Node implementation of [dart-sass](https://sass-lang.com/dart-sass) to parse `.scss` files into CSS.
120 |
121 | ```json
122 | {
123 | "devDependencies": {
124 | "sass": "^1.26.5"
125 | }
126 | }
127 | ```
128 |
129 | In the `sass.js` file, there's a `configs` object that you can use to control what `dart-sass` does.
130 |
131 | ```js
132 | // Configs
133 | var configs = {
134 | name: 'MyProject', // The name to use in the file banner
135 | files: ['main.scss'], // The files to process
136 | pathIn: 'src/scss', // The source directory for your Sass files
137 | pathOut: 'dist/css', // The directory to compile CSS files into
138 | indentType: 'tab', // The type of indenting to use ['tab'|'spaces']
139 | indentWidth: 1, // How many tabs or spaces to indent
140 | minify: true, // If true, a minified version will also be created with the .min suffix
141 | sourceMap: false, // If true, sourcemaps are created for each processed file †
142 | };
143 | ```
144 |
145 | A banner is automatically generated from your `package.json` data.
146 |
147 | It includes the project name and version, a copyright notice with the current year and the package author name, the license type, and a link to the project repository.
148 |
149 | _If a `configs.name` property is included, that will be used. If not, the banner defaults to the `name` property in your `package.json` file._
150 |
151 | ```js
152 | // Banner
153 | var banner = `/*! ${configs.name ? configs.name : pkg.name} v${pkg.version} | (c) ${new Date().getFullYear()} ${pkg.author.name} | ${pkg.license} License | ${pkg.repository.url} */`;
154 | ```
155 |
156 | Sass files should be in the `src/scss` directory. Use this task to run the build.
157 |
158 | ```bash
159 | npm run css
160 | ```
161 |
162 | _**Note for FireFox users:** ensure that ['Use Source Maps'](https://github.com/cferdinandi/build-tool-boilerplate/issues/7#issuecomment-811432626), and ['Show original sources'](https://github.com/cferdinandi/build-tool-boilerplate/issues/7#issuecomment-811855711) options are enabled in Developer Tools._
163 |
164 | ### SVG Optimization
165 |
166 | The template uses [svgo](https://github.com/svg/svgo) to remove the cruft that gets added to SVG files by many editors.
167 |
168 | ```json
169 | {
170 | "devDependencies": {
171 | "svgo": "^1.3.2"
172 | }
173 | }
174 | ```
175 |
176 | For accessibility reasons, the boilerplate disables the settings that remove the `title` element and `viewBox` attribute.
177 |
178 | You can make additional command line configurations under the `svg` tasks in the `scripts` property of the `package.json` file.
179 |
180 | ```bash
181 | svgo -f src/svg dist/svg -r --disable=removeViewBox,removeTitle
182 | ```
183 |
184 | SVGs should be in the `src/svg` directory. Use this task to run the build.
185 |
186 | ```bash
187 | npm run svg
188 | ```
189 |
190 |
191 | ### Image Optimization
192 |
193 | The template uses [imagemin](https://www.npmjs.com/package/imagemin), with the [MozJPEG](https://github.com/imagemin/imagemin-mozjpeg), [pngcrush](https://github.com/imagemin/imagemin-pngcrush), [pngquant](https://github.com/imagemin/imagemin-pngquant), and [zopfli](https://github.com/imagemin/imagemin-zopfli) plugins.
194 |
195 | (*Yea, that's kind of lot, isn't it?*)
196 |
197 | ```json
198 | {
199 | "devDependencies": {
200 | "imagemin-cli": "^6.0.0",
201 | "imagemin-mozjpeg": "^8.0.0",
202 | "imagemin-pngcrush": "^6.0.0",
203 | "imagemin-pngquant": "^8.0.0",
204 | "imagemin-zopfli": "^6.0.0"
205 | }
206 | }
207 | ```
208 |
209 | Image files should be in the `src/img` directory. Use this task to run the build.
210 |
211 | ```bash
212 | npm run img
213 | ```
214 |
215 | ### Copy Files
216 |
217 | The template uses [recursive-fs](https://github.com/simov/recursive-fs) to provide a cross-OS copying solution. This package is also used for the `clean` task, so only remove it if you're deleting both tasks.
218 |
219 | ```json
220 | {
221 | "devDependencies": {
222 | "recursive-fs": "^2.1.0"
223 | }
224 | }
225 | ```
226 |
227 | If you have files you want copied as-is, place them in the `src/copy` directory.
228 |
229 | Use this task to run the build.
230 |
231 | ```bash
232 | npm run copy
233 | ```
234 |
235 | ### Clean
236 |
237 | The template uses [recursive-fs](https://www.npmjs.com/package/recursive-fs) to provide a cross-OS recursive directory deleting solution. This package is also used for the `copy` task, so only remove it if you're deleting both tasks.
238 |
239 | ```json
240 | {
241 | "devDependencies": {
242 | "recursive-fs": "^2.1.0"
243 | }
244 | }
245 | ```
246 |
247 | You can delete the `/dist` directory before running a build to clean up any junk that might have ended up there. The `build` task runs this task before doing anything else.
248 |
249 | ```bash
250 | npm run clean
251 | ```
252 |
253 |
254 | ### Complete Build
255 |
256 | You can run all of your build tasks in a single command.
257 |
258 | Use this task to run the build.
259 |
260 | ```bash
261 | npm run build
262 | ```
263 |
264 | If you want to run your build _without_ first deleting the `/dist` directory, run this task instead.
265 |
266 | ```bash
267 | npm run build-dirty
268 | ```
269 |
270 | Regardless of which task you use, be sure to delete any tasks you're not using from the `build-dirty` task under `scripts` in your `package.json` file first. The `npm-run-all -p` command is used to run all tasks in parallel ([see below for more details](#core-dependencies)).
271 |
272 | ```bash
273 | # default build-dirty task
274 | npm-run-all -p js css svg img copy
275 | ```
276 |
277 | #### What 'build' DOES NOT do:
278 | - uglify all JS
279 | - bundle all JS into a single file.
280 | Instead, it bundles based on the input files you assign in the rollup config. So it is more modular.
281 |
282 | ### Watch for Changes
283 |
284 | The template uses [Chokidar CLI](https://www.npmjs.com/package/chokidar-cli) to watch for changes to the `/src` directory and run tasks in response.
285 |
286 | ```json
287 | {
288 | "devDependencies": {
289 | "chokidar-cli": "^2.1.0"
290 | }
291 | }
292 | ```
293 |
294 | Use this task to watch for changes and run a build. It will also run a fresh build when it starts.
295 |
296 | ```bash
297 | npm run watch
298 | ```
299 |
300 | If you only want to watch for changes to a specific directory in `/src`, you can use a task-specific watcher task.
301 |
302 | ```bash
303 | npm run watch-js # watch for changes to the /js directory
304 | npm run watch-css # watch for changes to the /css directory
305 | npm run watch-svg # watch for changes to the /svg directory
306 | npm run watch-img # watch for changes to the /img directory
307 | npm run watch-copy # watch for changes to the /copy directory
308 | ```
309 |
310 |
311 | ## Server
312 |
313 | The template uses [Browsersync](https://www.browsersync.io/) to run a local server and automatically update it whenever your files change.
314 |
315 | ```json
316 | {
317 | "devDependencies": {
318 | "browser-sync": "^2.26.14"
319 | }
320 | }
321 | ```
322 |
323 | Use this task to watch for changes. It will also run the `watch` task, and automatically rebuild whenever a file in `/src` changes.
324 |
325 | ```bash
326 | npm run server
327 | ```
328 |
329 | If you want to run the server _without_ the `watch` task, run this task instead.
330 |
331 | ```bash
332 | npm run server-start
333 | ```
334 |
335 |
336 |
337 | ## Core Dependencies
338 |
339 | The template uses [npm-run-all](https://www.npmjs.com/package/npm-run-all) to run tasks consistently across different operating systems, and in parallel.
340 |
341 | ```json
342 | {
343 | "devDependencies": {
344 | "npm-run-all": "^4.1.5"
345 | }
346 | }
347 | ```
348 |
349 | The `npm-run-all` package removes the need for Windows-specific tasks.
350 |
351 | It also allows you to run tasks in parallel. By running all of the tasks in the `build` tasks at the same time, you dramatically reduce the build time. This is also what makes it possible to run a localhost server _and_ watch for file changes in one task.
352 |
353 | **In other words, don't remove this dependency.**
354 |
355 |
356 |
357 | ## Why does this exist?
358 |
359 | I have been working with Webpack until now and I was never quite pleased with the way webpack worked.
360 | Too much magic for my taste. I wanted something simple and lean. I found Chris Ferdinandi's Boilerplate project and it
361 | was exactly what I was looking for. I added TypeScript and a test-framework.
362 |
--------------------------------------------------------------------------------