CodeCoupler Webpack Development Details: Boilerplate Files
All the files of the boilerplate explained:
.vscode/settings.json
| {
//Tell VSCode what type some files are:
"files.associations": {
"*.postcssrc": "json",
"*.lintstagedrc": "json"
"LICENSE": "plaintext",
"BANNER": "plaintext"
},
//Disable built-In Validators and let only stylelint validate and fix:
"css.validate": false,
"less.validate": false,
"scss.validate": false,
//We will use the linter markdownlint, eslint and stylelint to automatic fix code on save.
//ESLint and Stylelint are configured to work together with prettier which will format the code on
//save.
"eslint.enable": true,
"stylelint.enable": true,
"files.autoSave": "off",
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[javascript][vue][typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[css][scss][less]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[markdown]": {
"editor.defaultFormatter": "DavidAnson.vscode-markdownlint"
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.fixAll.stylelint": "explicit",
"source.fixAll.markdownlint": "explicit"
},
"editor.formatOnSave": true,
//Some Helper Extension for Comments and Markdown
"rewrap.autoWrap.enabled": true,
"markdowntable.formatOnSave": true,
//Unify tab sizes
"editor.tabSize": 2,
//Unify EOL
"files.eol": "\n"
//Removed support of Vetur in Boilerplate Version 2.2
//"vetur.validation.template": false,
//Enable linting for vue files
"eslint.validate": [
"javascript",
"javascriptreact",
"vue"
],
//Show all three breakpoints that will be uitilized by the boilerplates
"editor.rulers": [80, 100, 120]
}
|
.eslintrc
| {
// Starting with the global configuration for all JavaScript Files
// Use ignore pattern here instead of "".eslintignore". This will ensure working with
// nested configurations in workspaces.
"ignorePatterns": ["dist/", "node_modules/"],
"extends": [
// Set of rules which are recommended for all projects by the ESLint Team
"eslint:recommended",
// Rules for Vue validation
"plugin:vue/recommended",
// Enables eslint-plugin-prettier and eslint-config-prettier.
// Turns off all rules that are unnecessary or might conflict with Prettier
// This will display prettier errors as ESLint errors.
// Make sure this is always the last configuration in the extends array.
"plugin:prettier/recommended"
],
// Normally we have here to use babel as parser to recognize experimental features.
// But "vue-eslint-parser" have to be in first place. Therefore the babel parser is
// moved into "parserOptions.parser".
"parser": "vue-eslint-parser"
"parserOptions": {
// Parser to used internally by "vue-eslint-parser"
"parser": "@babel/eslint-parser",
// Using version 11 to allow dynamic imports and implement lazy loading
"ecmaVersion": 11,
"sourceType": "module",
// For linting files that are not transformed by Babel (such as tooling configuration files)
"requireConfigFile": false
},
"env": {
"browser": true,
"node": true,
"es6": true
},
// Plugins for parser and formatting rules
"plugins": ["babel", "prettier"],
"rules": {
// Add Prettier Ruls and use the file ".prettierc". With this the rules which will use
// ESLint are in sync with the rules that will be used by Prettier. After changing the
// ".prettierrc" file the ESLint server must be restartet!
"prettier/prettier": [
"error",
{},
{
"usePrettierrc": true
}
]
},
// Now override special configuration for TypeScript Files
"overrides": [
{
"files": ["**/*.ts"],
// Specifies the ESLint parser that will allow ESLint to lint TypeScript code
"parser": "@typescript-eslint/parser",
"extends": [
// set of rules which are recommended for all projects by the ESLint Team
"eslint:recommended",
// Uses the recommended rules from the @typescript-eslint/eslint-plugin
"plugin:@typescript-eslint/recommended",
// Enables eslint-plugin-prettier and eslint-config-prettier.
// This will display prettier errors as ESLint errors.
// Make sure this is always the last configuration in the extends array.
"plugin:prettier/recommended"
],
"parserOptions": {
// Using version 11 to allow dynamic imports and implement lazy loading
"ecmaVersion": 11,
"sourceType": "module"
},
"env": {
"browser": true,
"node": true,
"es6": true
},
"plugins": [
// A plugin that contains a bunch of ESLint rules that are TypeScript specific
"@typescript-eslint/eslint-plugin",
// Plugin with formatting rules
"prettier"
],
"rules": {
"prettier/prettier": [
"error",
{},
{
"usePrettierrc": true
}
]
}
}
]
}
|
.prettierc
The "trailingComma" was done to align the rules of the eslint-prettier-plugin rules and the default
prettier rules used by the IDE on save.
For HTML we like to have more space.
| {
"printWidth": 80,
"trailingComma": "none",
"overrides": [
{
"files": ["*.html", "*.vue"],
"options": {
"printWidth": 120
}
}
]
}
|
.markdownlint.json
This rule is disabled by default, because lines are often longer than 80 chars. But the markdown
looks odd has long lines and short lines distributed unevenly. Maybe a line length of 100 is a
better approach:
| {
"MD013": { "line_length": 100 }
}
|
.postcssrc
Compile modern (and experimental) CSS for targeted browsers defined in .browserslistrc
:
| {
"plugins": {
//
"postcss-preset-env": {
stage: 0
}
}
}
|
.stylelintrc
| {
// Moved from ".stylelintignore" because this will not work in monorepos
// with nested packages (https://github.com/stylelint/vscode-stylelint/issues/155).
"ignoreFiles": ["**/dist/**", "**/node_modules/**"],
// This configuration turns off all rules that might conflict with Prettier
"extends": [ "stylelint-config-standard", "stylelint-prettier/recommended" ],
"plugins": [ "stylelint-prettier" ],
"rules": {
"prettier/prettier": true,
// This addition make using CSS Module Pseudo Classes usable
"selector-pseudo-class-no-unknown": [
true,
{
"ignorePseudoClasses": [
"local",
"global"
]
}
]
}
}
|
tsconfig.json
| {
"compilerOptions": {
// The directory for the output
// Is this needed? Maybe because it will be automatically set as "exclude" glob.
"outDir": "./dist/",
// Is this needed?
"noImplicitAny": true,
// Without this (or with another value like "es6") we cannot use 'import "a-node-library"' from
// TypeScript files.
"module": "commonjs",
// Enable Decorators for class style vue apps
"experimentalDecorators": true,
// As we use babel this maybe is not needed, or other values acceptable.
// From Vue.js docs: This aligns with Vue's browser support
"target": "es5",
// Create source maps in combination with "devtool"
"sourceMap": true,
// From Vue.js docs:
// This enables stricter inference for data properties on `this`.
// Note that you have to include strict: true (or at least noImplicitThis: true which is a part
// of strict flag) to leverage type checking of this in component methods otherwise it is always
// treated as any type.
"strict": true,
//Support for Volar Plugin. Without this setting the plugin complain
//the tag <script> in vue files because of missing the attribute lang="ts"
"allowJs": true
// Vue.js docs note this two settings, but they are not used here:
// If using webpack 2+ or rollup, to leverage tree shaking:
// "module": "es2015",
// "moduleResolution": "node"
}
}
|
.gitignore
| # Dependency directories
node_modules/
# Transpiled source files
dist/
# Cache used by TypeScript's incremental build
*.tsbuildinfo
# Output of 'npm pack'
*.tgz
# Optional eslint cache
.eslintcache
|
husky setup: hook files, .lintstagedrc and package.json
In package.json
thusky will be initialized everytime npm i
is executed:
| {
"scripts": {
"prepare": "husky"
}
}
|
In the driectory .husky
the prepare commit script is defined in the pre-commit
file:
In .lintstagedrc
will be defined what files to lint before commit:
| {
"src/**/*.ts": "npm run tslint",
"src/**/*.js": "npm run jslint",
"src/**/*.vue": "npm run vuelint",
"src/**/*.css": "npm run csslint"
}
|
babel.config.json (.babelrc till version 4.4.0)
This will be used by Babel and the eslint-babel
Plugin.
| {
// This is the all-in-one preset which will manage all needed syntax transforms based on the
// target browsers configured in ".browserlistrc".
//
// To handle polyfills as well we have to set the "useBuiltIns" option. Otherwise an error
// "regeneratorRuntime is not defined" will be thrown if you use features like "async". This is
// because the preset will decide to use the plugin "@babel/plugin-transform-regenerator" and
// the runtime have to be globally accessible. See
// [https://github.com/babel/babel/issues/9849#issuecomment-487040428]
//
// To make this global accessible you could write in one point of your code (and it have) to be
// exactly one point) "import 'core-js'; import 'regenerator-runtime/runtime';". A better
// solution is to tell babel to handle all these imports. With "useBuiltIns: usage" all the
// needed import statements will be injected by babel. And then Webpack will do the rest. See
// [https://github.com/babel/babel/issues/9849#issuecomment-646245498]
//
// Furthermore we tell babel to use core-js version 3.41 and use also polyfills for proposals
// and not just for stable ECMAScript features. We have choosed 3.41 because this is the
// currently provided version in CodeCoupler Webpack. And It is recommended to specify the minor
// version otherwise "3" will be interpreted as "3.0" which may not include polyfills for the
// latest features. See [https://babeljs.io/docs/babel-preset-env#corejs]
//
// A last note: In package.json you will find the depndency to "core-js" which is needed to make
// everything work. But there is no dependency to "@babel/plugin-transform-regenerator". This is
// because this plugin is included as dependecy of "@babel/preset-env".
presets: [
[
"@babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": { "version": "3.41", "proposals": true }
}
]
],
// Under `useBuiltins: "usage"`, Babel needs to take a guess wrt. ES6 vs. CJS import styles; and
// it better guess the same way as Webpack. The simplest way to make that happen is to also set
// `sourceType: "unambiguous"` in the options. See [https://stackoverflow.com/a/68352125],
// [https://stackoverflow.com/a/52415747]
"sourceType": "unambiguous",
// Using Babel together with Webpack cause many different errors in case we do not exclude
// `node_modules` from the Webpack rules where `babel-loader` is used. We do not want to exclude
// all modules from transpiling, because it is sometimes usefull not only to bundle scripts from
// `node_modules`but also to transpile them, so we can use them in a browser context.
//
// In this case we have to exclude some of them explicitly from transpiling. First of all we have
// to exclude `core-js`. Because otherwise the transformation under `useBuiltins: "usage"` will
// actually be inserting references to core-js into itself causing dependency cycles.
//
// The Webpack documentation recommends excluding `node_modules/webpack/buildin` from this as
// well. From own observations, this is not enough, as errors and warnings are also seen when
// using the Webpack Dev Server. Therefore, we exclude all files that start with
// `node_modules/webpack`.
//
// Another problem is the combination of Babel, the `css-loader` and `mini-css-extract-plugin`.
// The produced javascript modules of the `css-loader` will be detected by babel any processed
// like any other javascript file. Since we have set `useBuiltins: "usage"` babel will include an
// import to a core-js polyfill, which use a function named `$`. This function is not available
// when `mini-css-extract-plugin` gets the code, which leads to an error.
//
// See:
//
// - [https://github.com/webpack-contrib/mini-css-extract-plugin/issues/471#issuecomment-750266195]
// - [https://stackoverflow.com/a/58517865]
// - [https://stackoverflow.com/a/68836211]
// - [https://webpack.js.org/loaders/babel-loader/#exclude-libraries-that-should-not-be-transpiled]
// - [https://stackoverflow.com/a/52415747]
"ignore": [
"node_modules/css-loader",
"node_modules/core-js",
"node_modules/webpack"
],
// This one will be added only in production mode and will strip "console.debug"
// statements away.
"env": {
"production": {
"plugins": [
["strip-function-call", {
"strip": ["console.debug"]
}]
]
}
}
}
|
.browserlistrc
Many components access this configuration. The included .browserlistrc
contains only a very basic
configuration:
| last 1 version
> 1%
not dead
|
Just one note: Do not include node targets like maintained node versions
because Webpack 5 will
throw an error: https://github.com/webpack/webpack/issues/11660