Skip to content

Commit

Permalink
Add first class Javascript/Typescript support to the Mill build tool (#…
Browse files Browse the repository at this point in the history
…4398)

This pr implements the examples for jslib/dependencies.

#3927

Checklist:
- [x] **example/jslib/linting**
     - [x]  1-linting
     - [x]  2-autoformatting
     - [x]  3-code-coverage
     
Key changes:
- Add coverage for Jest, Jasmine, Mocha and Vitest.
- Add lint and auto format support with prettier and eslint.
- Generate test config for Jest & Vite, with option to use a custom test
config.

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Li Haoyi <haoyi.sg@gmail.com>
  • Loading branch information
3 people authored Jan 29, 2025
1 parent 583151e commit da80000
Show file tree
Hide file tree
Showing 34 changed files with 1,092 additions and 343 deletions.
1 change: 1 addition & 0 deletions docs/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
*** xref:javascriptlib/module-config.adoc[]
*** xref:javascriptlib/testing.adoc[]
*** xref:javascriptlib/publishing.adoc[]
*** xref:javascriptlib/linting.adoc[]
* xref:comparisons/why-mill.adoc[]
** xref:comparisons/maven.adoc[]
** xref:comparisons/gradle.adoc[]
Expand Down
21 changes: 21 additions & 0 deletions docs/modules/ROOT/pages/javascriptlib/linting.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
= Linting Typescript Projects
:page-aliases: Linting_Typescript_Projects.adoc

include::partial$gtag-config.adoc[]

This page will discuss common topics around maintaining the code quality of Typescript
codebases using the Mill build tool

== Linting and AutoFormatting with Eslint and Prettier

Eslint and Prettier are tools that analyzes your Typescript source code, performing intelligent analyses and code quality checks, and is often able to automatically fix the issues that it discovers. It can also perform automated refactoring.

include::partial$example/javascriptlib/linting/1-linting.adoc[]

include::partial$example/javascriptlib/linting/2-autoformatting.adoc[]

== Code Coverage with Jest, Mocha, Vitest and Jasmine

Mill supports code coverage analysis with multiple Typescript testing frameworks.

include::partial$example/javascriptlib/linting/3-code-coverage.adoc[]
31 changes: 0 additions & 31 deletions example/javascriptlib/basic/1-simple/jest.config.ts

This file was deleted.

31 changes: 0 additions & 31 deletions example/javascriptlib/basic/3-custom-build-logic/jest.config.ts

This file was deleted.

31 changes: 0 additions & 31 deletions example/javascriptlib/basic/4-multi-modules/jest.config.ts

This file was deleted.

31 changes: 0 additions & 31 deletions example/javascriptlib/basic/5-client-server-hello/jest.config.ts

This file was deleted.

This file was deleted.

43 changes: 43 additions & 0 deletions example/javascriptlib/linting/1-linting/build.mill
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package build

import mill._, javascriptlib._

object foo extends TypeScriptModule with TsLintModule

// Mill supports code linting via `eslint` https://eslint.org out of the box.
// You can lint your projects code by providing a configuration for eslint and running `mill _.checkFormatAll`.

// You can define `npmLintDeps` field to add dependencies specific to linting to your module.
// The task `npmLintDeps` works the same way as `npmDeps` or `npmDevDeps`.

/** Usage
> cat foo/src/foo.ts # initial code with lint errors.
export class Foo{
static main(
args: string[
]) {
console.log(`Hello World`);
}
}

> mill foo.checkFormatAll # run eslint
...
foo/src/foo.ts
3:5 error 'args' is defined but never used @typescript-eslint/no-unused-vars
...
...1 problem (1 error, 0 warnings)

> sed -i.bak 's/Hello World/Hello World ${args.join('\'' '\'')}/' foo/src/foo.ts # fix lint error.

> cat foo/src/foo.ts # initial code with lint errors.
export class Foo{
static main(
args: string[
]) {
console.log(`Hello World ${args.join(' ')}`);
}
}

> mill foo.checkFormatAll # run eslint
All matched files use Eslint code style!
*/
32 changes: 32 additions & 0 deletions example/javascriptlib/linting/1-linting/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// @ts-check

import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';

export default tseslint.config({
files: ['*/**/*.ts'],
extends: [
eslint.configs.recommended,
...tseslint.configs.recommended,
],
rules: {
// styling rules
'semi': ['error', 'always'],
'comma-dangle': ['error', 'always-multiline'],
'max-len': ['error', {code: 80, ignoreUrls: true}],
'indent': ['error', 2, {SwitchCase: 1}],
'brace-style': ['error', '1tbs'],
'space-before-function-paren': ['error', 'never'],
'no-multi-spaces': 'error',
'array-bracket-spacing': ['error', 'never'],
'object-curly-spacing': ['error', 'always'],
'arrow-spacing': ['error', {before: true, after: true}],
'key-spacing': ['error', {beforeColon: false, afterColon: true}],
'keyword-spacing': ['error', {before: true, after: true}],
'space-infix-ops': 'error',
'block-spacing': ['error', 'always'],
'eol-last': ['error', 'always'],
'newline-per-chained-call': ['error', {ignoreChainWithDepth: 2}],
'padded-blocks': ['error', 'never'],
},
});
7 changes: 7 additions & 0 deletions example/javascriptlib/linting/1-linting/foo/src/foo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export class Foo{
static main(
args: string[
]) {
console.log(`Hello World`);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
dist
build
.git
7 changes: 7 additions & 0 deletions example/javascriptlib/linting/2-autoformatting/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"semi": true,
"trailingComma": "all",
"singleQuote": true,
"printWidth": 80,
"tabWidth": 2
}
80 changes: 80 additions & 0 deletions example/javascriptlib/linting/2-autoformatting/build.mill
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package build

import mill._, javascriptlib._

object foo extends TypeScriptModule with TsLintModule

// Mill supports code auto formatting via `eslint` https://eslint.org and `prettier` https://prettier.io/docs/en.
// You can reformat your projects code by providing a configuration for your preferred formtter then running
// `mill _.reformatAll` to reformat your code. You can also check for formatting errors by running
// `mill _.checkFormatAll`.

// If both configuration files are present, the command `mill _.checkFormatAll` and
// `mill _.reformatAll` will default to eslint. If neither files are present,
// the command will exit with an error, you must include at least one configuration file.

// When using prettier you can specify the path to check format or reformat via command line argument,
// `mill _.checkFormatAll "*/**/*.ts"` just as you would when running `prettier --check` or
// `mill _.reformatAll "*/**/*.ts"` just as you would when running `prettier --write`,
// if no path is provided mill will default to using "*/**/*.ts".
//
// Also if a `.prettierignore` is not provided, mill will generate one ignoring "node_modules" and ".git".

/** Usage
> cat foo/src/foo.ts # initial poorly formatted source code
export class Foo{
static main(
args: string[
])
{console.log("Hello World!")
}
}

> mill foo.checkFormatAll # run linter - since both eslint and prettier configurations are present, mill will opt to use eslint.
...
foo/src/foo.ts
2:1 error Expected indentation of 2 spaces but found 0 indent
3:1 error Expected indentation of 4 spaces but found 0 indent
5:1 error Opening curly brace does not appear on the same line as controlling statement brace-style
5:1 error Statement inside of curly braces should be on next line brace-style
5:1 error Requires a space after '{' block-spacing
5:1 error Expected indentation of 2 spaces but found 0 indent
5:14 error Strings must use singlequote quotes
5:29 error Missing semicolon semi
6:1 error Expected indentation of 2 spaces but found 0 indent
7:2 error Newline required at end of file but not found eol-last
...
...10 problems (10 errors, 0 warnings)
...10 errors and 0 warnings potentially fixable with running foo.reformatAll.

> mill foo.reformatAll
...
All matched files have been reformatted!

> cat foo/src/foo.ts # code formatted with eslint configuration.
export class Foo{
static main(
args: string[
]) {
console.log('Hello World!');
}
}

> rm -rf eslint.config.mjs # since there is no eslint config file `eslint.config.(js|mjs|cjs)`, mill will use the prettier configuration available.

> mill foo.checkFormatAll # run lint with prettier configuration.
Checking formatting...
[warn] foo/src/foo.ts
[warn] Code style issues found. Run foo.reformatAll to fix.

> mill foo.reformatAll
...
All matched files have been reformatted!

> cat foo/src/foo.ts # code formatted with prettier configuration.
export class Foo {
static main(args: string[]) {
console.log('Hello World!');
}
}
*/
Loading

0 comments on commit da80000

Please sign in to comment.