├── src ├── content │ └── index.js ├── background │ └── index.js ├── images │ └── icon256.png ├── popup │ ├── index.css │ ├── index.js │ ├── index.html │ └── App.js └── manifest.json ├── .parcelrc ├── .gitignore ├── .idea ├── .gitignore ├── vcs.xml ├── jsLibraryMappings.xml ├── inspectionProfiles │ └── Project_Default.xml ├── modules.xml ├── mv3-parcel-webext-template.iml └── jsonSchemas.xml ├── .env.example ├── .github └── dependabot.yml ├── utils ├── remove-source-maps.mjs └── create-zip.mjs ├── .eslintrc.json ├── LICENSE ├── .release-it.js ├── package.json ├── README.md └── .editorconfig /src/content/index.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/background/index.js: -------------------------------------------------------------------------------- 1 | console.log('Service worker'); 2 | -------------------------------------------------------------------------------- /.parcelrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@parcel/config-webextension" 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | /dist 3 | /releases 4 | /.parcel-cache/ 5 | .env 6 | -------------------------------------------------------------------------------- /src/images/icon256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onikienko/mv3-parcel-webext-template/HEAD/src/images/icon256.png -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | -------------------------------------------------------------------------------- /src/popup/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | text-align: center; 3 | background-color: #292a2d; 4 | color: #ffffff; 5 | margin: 20px; 6 | } 7 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | # rename this file to .env 2 | GITHUB_TOKEN="you may get it by following this link https://github.com/settings/tokens/new?scopes=repo&description=release-it" 3 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "npm" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | open-pull-requests-limit: 10 8 | -------------------------------------------------------------------------------- /src/popup/index.js: -------------------------------------------------------------------------------- 1 | import ReactDom from 'react-dom/client'; 2 | import {App} from './App'; 3 | import './index.css'; 4 | 5 | 6 | const root = ReactDom.createRoot(document.getElementById('root')); 7 | root.render(); 8 | -------------------------------------------------------------------------------- /.idea/jsLibraryMappings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/popup/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /src/popup/App.js: -------------------------------------------------------------------------------- 1 | import logo from 'url:../images/icon256.png'; 2 | 3 | 4 | export const App = () => { 5 | return ( 6 | <> 7 | Logo 8 |

Popup Window

9 |
v{chrome.runtime.getManifest().version}
10 | 11 | ); 12 | }; 13 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /utils/remove-source-maps.mjs: -------------------------------------------------------------------------------- 1 | import {glob} from 'glob'; 2 | import {readFileSync, unlinkSync, writeFileSync} from 'node:fs'; 3 | 4 | 5 | (async () => { 6 | const mapFiles = await glob('dist/**/*.map'); 7 | mapFiles.forEach(file => unlinkSync(file)); 8 | 9 | const files = await glob('dist/**/*.+(css|js)'); 10 | files.forEach(file => { 11 | const data = readFileSync(file, {encoding: 'utf8'}); 12 | const res = data.replace(/\/[*|\/]# sourceMappingURL=.+\n/, ''); 13 | writeFileSync(file, res); 14 | }); 15 | })(); 16 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2022": true, 5 | "node": true, 6 | "webextensions": true 7 | }, 8 | "extends": [ 9 | "eslint:recommended", 10 | "plugin:react/recommended", 11 | "plugin:react-hooks/recommended" 12 | ], 13 | "parserOptions": { 14 | "ecmaFeatures": { 15 | "jsx": true 16 | }, 17 | "sourceType": "module" 18 | }, 19 | "plugins": [ 20 | "react", 21 | "react-hooks" 22 | ], 23 | "rules": { 24 | "react/prop-types": 0, 25 | "react/jsx-uses-react": "off", 26 | "react/react-in-jsx-scope": "off" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /utils/create-zip.mjs: -------------------------------------------------------------------------------- 1 | import filenamify from 'filenamify'; 2 | import {readFileSync} from 'node:fs'; 3 | import path from 'node:path'; 4 | import zl from 'zip-lib'; 5 | 6 | 7 | const DIST_DIR = './dist'; 8 | const RELEASE_DIR = './releases'; 9 | 10 | const {name, version} = JSON.parse(readFileSync('./package.json', {encoding: 'utf8'})); 11 | const extName = filenamify(name, {replacement: '_'}); 12 | const zipName = `${extName}-v${version}.zip`; 13 | const zipPath = path.join(RELEASE_DIR, zipName); 14 | 15 | zl.archiveFolder(DIST_DIR, zipPath) 16 | .then(() => console.log(`Release zip created - ${zipPath}`)); 17 | -------------------------------------------------------------------------------- /src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 3, 3 | "name": "mv3-parcel-webext-template", 4 | "description": "Extension Description", 5 | "version": "0.0.0", 6 | "icons": { 7 | "16": "images/icon256.png?width=16", 8 | "24": "images/icon256.png?width=24", 9 | "32": "images/icon256.png?width=32", 10 | "48": "images/icon256.png?width=48", 11 | "64": "images/icon256.png?width=64", 12 | "128": "images/icon256.png?width=128", 13 | "256": "images/icon256.png" 14 | }, 15 | "background": { 16 | "service_worker": "background/index.js", 17 | "type": "module" 18 | }, 19 | "action": { 20 | "default_popup": "popup/index.html" 21 | }, 22 | "permissions": [] 23 | } 24 | -------------------------------------------------------------------------------- /.idea/mv3-parcel-webext-template.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /.idea/jsonSchemas.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Mykhailo Onikiienko 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.release-it.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 'git': { 3 | 'requireCleanWorkingDir': true, 4 | 'commitMessage': 'v${version}', 5 | 'pushRepo': 'origin', 6 | 'tagName': 'v${version}', 7 | 'requireCommits': true, 8 | }, 9 | // docs https://github.com/release-it/release-it/blob/main/docs/github-releases.md 10 | 'github': { 11 | 'release': true, 12 | 'releaseName': 'v${version}', 13 | 'tokenRef': 'GITHUB_TOKEN', 14 | 'assets': ['releases/*-v${version}.zip'], 15 | }, 16 | 'plugins': { 17 | '@release-it/bumper': { 18 | // bump a version in the manifest.json 19 | 'out': { 20 | 'file': 'src/manifest.json', 21 | }, 22 | }, 23 | '@release-it/conventional-changelog': { 24 | 'infile': 'CHANGELOG.md', 25 | 'ignoreRecommendedBump': true, 26 | 'preset': { 27 | 'name': 'conventionalcommits', 28 | 'types': [ 29 | { 30 | 'type': 'feat', 31 | 'section': 'Features', 32 | }, 33 | { 34 | 'type': 'fix', 35 | 'section': 'Bug Fixes', 36 | }, 37 | ], 38 | }, 39 | }, 40 | }, 41 | 'npm': { 42 | 'publish': false, 43 | }, 44 | 'hooks': { 45 | 'after:bump': ['npm run build'], 46 | 'after:release': [ 47 | 'echo Successfully released ${name} v${version} to ${repo.repository}', 48 | 'opener ${releaseUrl}', 49 | ], 50 | }, 51 | }; 52 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mv3-parcel-webext-template", 3 | "version": "0.0.0", 4 | "description": "Chrome Extension boilerplate for manifest v3. With React.", 5 | "scripts": { 6 | "start": "parcel watch src/manifest.json --host localhost", 7 | "prebuild": "rimraf dist .parcel-cache", 8 | "build": "parcel build src/manifest.json --no-cache", 9 | "postbuild": "node utils/remove-source-maps.mjs && node utils/create-zip.mjs", 10 | "release": "dotenv release-it --" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/onikienko/mv3-parcel-webext-template.git" 15 | }, 16 | "author": "Mykhailo Onikiienko (https://github.com/onikienko)", 17 | "license": "MIT", 18 | "bugs": { 19 | "url": "https://github.com/onikienko/mv3-parcel-webext-template/issues" 20 | }, 21 | "homepage": "https://github.com/onikienko/mv3-parcel-webext-template#readme", 22 | "devDependencies": { 23 | "@parcel/config-webextension": "^2.13.3", 24 | "@release-it/bumper": "^7.0.5", 25 | "@release-it/conventional-changelog": "^10.0.3", 26 | "@types/chrome": "^0.1.32", 27 | "@types/react": "^19.2.7", 28 | "@types/react-dom": "^19.2.3", 29 | "dotenv-cli": "^11.0.0", 30 | "eslint": "^8.57.1", 31 | "eslint-plugin-react": "^7.37.5", 32 | "eslint-plugin-react-hooks": "^4.6.2", 33 | "filenamify": "^7.0.0", 34 | "glob": "^13.0.0", 35 | "opener": "^1.5.2", 36 | "parcel": "^2.13.3", 37 | "process": "^0.11.10", 38 | "release-it": "^19.1.0", 39 | "rimraf": "^6.1.2", 40 | "sharp": "^0.33.5", 41 | "zip-lib": "^1.1.2" 42 | }, 43 | "dependencies": { 44 | "react": "^19.2.3", 45 | "react-dom": "^19.2.3" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mv3-parcel-webext-template 2 | 3 | Chrome Extension boilerplate for manifest v3. 4 | 5 | 6 | This template uses [Parcel Web Extension Config](https://parceljs.org/recipes/web-extension/) 7 | and [release-it](https://github.com/release-it/release-it) for GitHub releases. 8 | 9 | ## How to use 10 | 11 | - Click [Use this template](https://github.com/onikienko/mv3-parcel-webext-template/generate) button on the top of the page. 12 | - After project initialization, change the `name` field in the `package.json` file. This field will be used as a name 13 | for `.zip` with production build. 14 | - Update `repository`, `author`, `bugs`, `license`, and `homepage` props in `package.json` according to your needs. 15 | - There is configured [Dependabot version updates](https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/about-dependabot-version-updates). 16 | If you do not want PRs with your dependency version updates, remove the `.github/dependabot.yml` file. 17 | 18 | ### Development: 19 | 20 | 1. Check if your [Node.js](https://nodejs.org/) version is >= **20**. 21 | 2. Run `npm install` to install the dependencies. 22 | 3. Run `npm start` 23 | 4. Load your extension on Chrome following: 24 | 1. Access `chrome://extensions/` 25 | 2. Check `Developer mode` 26 | 3. Click on `Load unpacked extension` 27 | 4. Select the `dist` folder. 28 | 29 | ### Production build: 30 | 31 | 1. Stop the development script (if it is running) 32 | 2. Run `npm run build` 33 | 3. Load your extension on Chrome following: 34 | 1. Access `chrome://extensions/` 35 | 2. Check `Developer mode` 36 | 3. Click on `Load unpacked extension` 37 | 4. Select the `dist` folder 38 | 39 | `zip` file with the production extension's code will be created in the `releases` folder. 40 | This code is ready to be published in the Chrome Web Store. 41 | 42 | ### Release: 43 | 44 | During the `release` script execution you will be asked for a new version number, so there is no need to change the version manually. 45 | The script will bump the version in `package.json` and `manifest.json`. 46 | 47 | This template uses [release-it](https://github.com/release-it/release-it) for release on GitHub. 48 | 49 | 1. Generate `personal access token` in GitHub. Go to 50 | [Github->Settings->DeveloperSettings->PersonalAccessTokens](https://github.com/settings/tokens/new?scopes=repo&description=release-it). 51 | Only `repo` scope is required. 52 | 2. Rename the existing `.env.example` file to `.env` and put the generated `personal access token` there. It will look 53 | like: 54 | ``` 55 | GITHUB_TOKEN="your generated token" 56 | ``` 57 | 3. Run `npm run release`. Under the hood, it will make a version bump (in both `package.json` and `manifest.json`), 58 | run `npm run build` steps, commit, push, and make a GitHub release with the generated `zip` file attached. 59 | 60 | ## Known issues 61 | 62 | Parcel Web Extension Config [does not support](https://github.com/parcel-bundler/parcel/issues/5758) `scripting` API 63 | (`executeScript`, `insertCSS`, etc.) 64 | As a workaround, take a look at the recipe below. 65 | 66 | ## Recipes 67 | 68 | ### Usage with `chrome.scripting` API 69 | 70 | If you need to inject scripts dynamically using `chrome.scripting` API, you could add these scripts to `manifest.json` 71 | as an additional entry point. 72 | 73 | For such code 74 | 75 | ```javaScript 76 | chrome.scripting.executeScript({ 77 | target: {tabId}, 78 | files: ["checker/index.js"], 79 | }) 80 | ``` 81 | 82 | you could update your scripts in `manifest.json` like this: 83 | 84 | ``` 85 | "start": "parcel watch src/manifest.json src/checker/index.js --host localhost", 86 | "build": "parcel build src/manifest.json src/checker/index.js --no-cache" 87 | ``` 88 | 89 | If you need to use assets in such a dynamically injected script, 90 | put them in `web_accessible_resources` in your `manifest.json`: 91 | 92 | ``` 93 | "web_accessible_resources": [ 94 | { 95 | "resources": [ 96 | "web-accessible/icon.png" 97 | ], 98 | "matches": [ 99 | "" 100 | ] 101 | } 102 | ] 103 | ``` 104 | 105 | And in your code, you will need to use them like 106 | 107 | ```javaScript 108 | 109 | ``` 110 | 111 | Do not use `import icon from "./web-accessible/icon.png"` in such scripts. 112 | 113 | ### If you need to have a page not listed in `manifest.json` 114 | 115 | The same goes for a page(s) not listed in `manifest.json`. 116 | You can add it as an additional entry point(s). 117 | 118 | Something like that: 119 | 120 | ``` 121 | "start": "parcel watch src/manifest.json src/panel/panel.html --host localhost", 122 | "build": "parcel build src/manifest.json src/panel/panel.html --no-cache" 123 | ``` 124 | 125 | In that case `panel` folder will be created in `dist` and you can reference it from your code like `panel/panel.html`. 126 | 127 | You can take a look at this [example](https://github.com/onikienko/keygenjukebox-play-button/tree/master/mv3). There is an additional entry point (`offscreen.html`) that is not listed in `manifest.json` (`chrome.offscreen` API usage). 128 | 129 | ### How to get rid of React 130 | 131 | If you do not need to use React in your extension: 132 | 133 | ```shell 134 | npm uninstall react react-dom @types/react @types/react-dom eslint-plugin-react eslint-plugin-react-hooks 135 | ``` 136 | 137 | React is used only in `popup`, 138 | so remove `src/popup/App.js` and update `src/popup/index.js` to meet your needs. 139 | 140 | In the `.eslintrc.json` file remove all the strings related to `react` (in `extends`, `plugins`, and `rules` props ). 141 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = crlf 6 | indent_size = 4 7 | indent_style = space 8 | insert_final_newline = true 9 | max_line_length = 120 10 | tab_width = 4 11 | trim_trailing_whitespace = true 12 | ij_continuation_indent_size = 8 13 | ij_formatter_off_tag = @formatter:off 14 | ij_formatter_on_tag = @formatter:on 15 | ij_formatter_tags_enabled = false 16 | ij_smart_tabs = false 17 | ij_visual_guides = none 18 | ij_wrap_on_typing = false 19 | 20 | [*.css] 21 | ij_css_align_closing_brace_with_properties = false 22 | ij_css_blank_lines_around_nested_selector = 1 23 | ij_css_blank_lines_between_blocks = 1 24 | ij_css_block_comment_add_space = false 25 | ij_css_brace_placement = end_of_line 26 | ij_css_enforce_quotes_on_format = false 27 | ij_css_hex_color_long_format = false 28 | ij_css_hex_color_lower_case = false 29 | ij_css_hex_color_short_format = false 30 | ij_css_hex_color_upper_case = false 31 | ij_css_keep_blank_lines_in_code = 2 32 | ij_css_keep_indents_on_empty_lines = false 33 | ij_css_keep_single_line_blocks = false 34 | ij_css_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow 35 | ij_css_space_after_colon = true 36 | ij_css_space_before_opening_brace = true 37 | ij_css_use_double_quotes = true 38 | ij_css_value_alignment = do_not_align 39 | 40 | [.editorconfig] 41 | ij_editorconfig_align_group_field_declarations = false 42 | ij_editorconfig_space_after_colon = false 43 | ij_editorconfig_space_after_comma = true 44 | ij_editorconfig_space_before_colon = false 45 | ij_editorconfig_space_before_comma = false 46 | ij_editorconfig_spaces_around_assignment_operators = true 47 | 48 | [{*.cjs,*.js}] 49 | ij_continuation_indent_size = 4 50 | ij_javascript_align_imports = false 51 | ij_javascript_align_multiline_array_initializer_expression = false 52 | ij_javascript_align_multiline_binary_operation = false 53 | ij_javascript_align_multiline_chained_methods = false 54 | ij_javascript_align_multiline_extends_list = false 55 | ij_javascript_align_multiline_for = true 56 | ij_javascript_align_multiline_parameters = true 57 | ij_javascript_align_multiline_parameters_in_calls = false 58 | ij_javascript_align_multiline_ternary_operation = false 59 | ij_javascript_align_object_properties = 0 60 | ij_javascript_align_union_types = false 61 | ij_javascript_align_var_statements = 0 62 | ij_javascript_array_initializer_new_line_after_left_brace = false 63 | ij_javascript_array_initializer_right_brace_on_new_line = false 64 | ij_javascript_array_initializer_wrap = off 65 | ij_javascript_assignment_wrap = off 66 | ij_javascript_binary_operation_sign_on_next_line = false 67 | ij_javascript_binary_operation_wrap = off 68 | ij_javascript_blacklist_imports = rxjs/Rx, node_modules/**, **/node_modules/**, @angular/material, @angular/material/typings/** 69 | ij_javascript_blank_lines_after_imports = 2 70 | ij_javascript_blank_lines_around_class = 1 71 | ij_javascript_blank_lines_around_field = 0 72 | ij_javascript_blank_lines_around_function = 1 73 | ij_javascript_blank_lines_around_method = 1 74 | ij_javascript_block_brace_style = end_of_line 75 | ij_javascript_block_comment_add_space = false 76 | ij_javascript_block_comment_at_first_column = true 77 | ij_javascript_call_parameters_new_line_after_left_paren = false 78 | ij_javascript_call_parameters_right_paren_on_new_line = false 79 | ij_javascript_call_parameters_wrap = off 80 | ij_javascript_catch_on_new_line = false 81 | ij_javascript_chained_call_dot_on_new_line = true 82 | ij_javascript_class_brace_style = end_of_line 83 | ij_javascript_comma_on_new_line = false 84 | ij_javascript_do_while_brace_force = never 85 | ij_javascript_else_on_new_line = false 86 | ij_javascript_enforce_trailing_comma = whenmultiline 87 | ij_javascript_extends_keyword_wrap = off 88 | ij_javascript_extends_list_wrap = off 89 | ij_javascript_field_prefix = _ 90 | ij_javascript_file_name_style = relaxed 91 | ij_javascript_finally_on_new_line = false 92 | ij_javascript_for_brace_force = never 93 | ij_javascript_for_statement_new_line_after_left_paren = false 94 | ij_javascript_for_statement_right_paren_on_new_line = false 95 | ij_javascript_for_statement_wrap = off 96 | ij_javascript_force_quote_style = true 97 | ij_javascript_force_semicolon_style = true 98 | ij_javascript_function_expression_brace_style = end_of_line 99 | ij_javascript_if_brace_force = never 100 | ij_javascript_import_merge_members = global 101 | ij_javascript_import_prefer_absolute_path = global 102 | ij_javascript_import_sort_members = true 103 | ij_javascript_import_sort_module_name = true 104 | ij_javascript_import_use_node_resolution = true 105 | ij_javascript_imports_wrap = on_every_item 106 | ij_javascript_indent_case_from_switch = true 107 | ij_javascript_indent_chained_calls = true 108 | ij_javascript_indent_package_children = 0 109 | ij_javascript_jsx_attribute_value = braces 110 | ij_javascript_keep_blank_lines_in_code = 2 111 | ij_javascript_keep_first_column_comment = true 112 | ij_javascript_keep_indents_on_empty_lines = false 113 | ij_javascript_keep_line_breaks = true 114 | ij_javascript_keep_simple_blocks_in_one_line = false 115 | ij_javascript_keep_simple_methods_in_one_line = false 116 | ij_javascript_line_comment_add_space = true 117 | ij_javascript_line_comment_at_first_column = false 118 | ij_javascript_method_brace_style = end_of_line 119 | ij_javascript_method_call_chain_wrap = off 120 | ij_javascript_method_parameters_new_line_after_left_paren = false 121 | ij_javascript_method_parameters_right_paren_on_new_line = false 122 | ij_javascript_method_parameters_wrap = off 123 | ij_javascript_object_literal_wrap = on_every_item 124 | ij_javascript_parentheses_expression_new_line_after_left_paren = false 125 | ij_javascript_parentheses_expression_right_paren_on_new_line = false 126 | ij_javascript_place_assignment_sign_on_next_line = false 127 | ij_javascript_prefer_as_type_cast = false 128 | ij_javascript_prefer_explicit_types_function_expression_returns = false 129 | ij_javascript_prefer_explicit_types_function_returns = false 130 | ij_javascript_prefer_explicit_types_vars_fields = false 131 | ij_javascript_prefer_parameters_wrap = false 132 | ij_javascript_reformat_c_style_comments = false 133 | ij_javascript_space_after_colon = true 134 | ij_javascript_space_after_comma = true 135 | ij_javascript_space_after_dots_in_rest_parameter = false 136 | ij_javascript_space_after_generator_mult = true 137 | ij_javascript_space_after_property_colon = true 138 | ij_javascript_space_after_quest = true 139 | ij_javascript_space_after_type_colon = true 140 | ij_javascript_space_after_unary_not = false 141 | ij_javascript_space_before_async_arrow_lparen = true 142 | ij_javascript_space_before_catch_keyword = true 143 | ij_javascript_space_before_catch_left_brace = true 144 | ij_javascript_space_before_catch_parentheses = true 145 | ij_javascript_space_before_class_lbrace = true 146 | ij_javascript_space_before_class_left_brace = true 147 | ij_javascript_space_before_colon = true 148 | ij_javascript_space_before_comma = false 149 | ij_javascript_space_before_do_left_brace = true 150 | ij_javascript_space_before_else_keyword = true 151 | ij_javascript_space_before_else_left_brace = true 152 | ij_javascript_space_before_finally_keyword = true 153 | ij_javascript_space_before_finally_left_brace = true 154 | ij_javascript_space_before_for_left_brace = true 155 | ij_javascript_space_before_for_parentheses = true 156 | ij_javascript_space_before_for_semicolon = false 157 | ij_javascript_space_before_function_left_parenth = true 158 | ij_javascript_space_before_generator_mult = false 159 | ij_javascript_space_before_if_left_brace = true 160 | ij_javascript_space_before_if_parentheses = true 161 | ij_javascript_space_before_method_call_parentheses = false 162 | ij_javascript_space_before_method_left_brace = true 163 | ij_javascript_space_before_method_parentheses = false 164 | ij_javascript_space_before_property_colon = false 165 | ij_javascript_space_before_quest = true 166 | ij_javascript_space_before_switch_left_brace = true 167 | ij_javascript_space_before_switch_parentheses = true 168 | ij_javascript_space_before_try_left_brace = true 169 | ij_javascript_space_before_type_colon = false 170 | ij_javascript_space_before_unary_not = false 171 | ij_javascript_space_before_while_keyword = true 172 | ij_javascript_space_before_while_left_brace = true 173 | ij_javascript_space_before_while_parentheses = true 174 | ij_javascript_spaces_around_additive_operators = true 175 | ij_javascript_spaces_around_arrow_function_operator = true 176 | ij_javascript_spaces_around_assignment_operators = true 177 | ij_javascript_spaces_around_bitwise_operators = true 178 | ij_javascript_spaces_around_equality_operators = true 179 | ij_javascript_spaces_around_logical_operators = true 180 | ij_javascript_spaces_around_multiplicative_operators = true 181 | ij_javascript_spaces_around_relational_operators = true 182 | ij_javascript_spaces_around_shift_operators = true 183 | ij_javascript_spaces_around_unary_operator = false 184 | ij_javascript_spaces_within_array_initializer_brackets = false 185 | ij_javascript_spaces_within_brackets = false 186 | ij_javascript_spaces_within_catch_parentheses = false 187 | ij_javascript_spaces_within_for_parentheses = false 188 | ij_javascript_spaces_within_if_parentheses = false 189 | ij_javascript_spaces_within_imports = false 190 | ij_javascript_spaces_within_interpolation_expressions = false 191 | ij_javascript_spaces_within_method_call_parentheses = false 192 | ij_javascript_spaces_within_method_parentheses = false 193 | ij_javascript_spaces_within_object_literal_braces = false 194 | ij_javascript_spaces_within_object_type_braces = true 195 | ij_javascript_spaces_within_parentheses = false 196 | ij_javascript_spaces_within_switch_parentheses = false 197 | ij_javascript_spaces_within_type_assertion = false 198 | ij_javascript_spaces_within_union_types = true 199 | ij_javascript_spaces_within_while_parentheses = false 200 | ij_javascript_special_else_if_treatment = true 201 | ij_javascript_ternary_operation_signs_on_next_line = false 202 | ij_javascript_ternary_operation_wrap = off 203 | ij_javascript_union_types_wrap = on_every_item 204 | ij_javascript_use_chained_calls_group_indents = false 205 | ij_javascript_use_double_quotes = false 206 | ij_javascript_use_explicit_js_extension = auto 207 | ij_javascript_use_path_mapping = always 208 | ij_javascript_use_public_modifier = false 209 | ij_javascript_use_semicolon_after_statement = true 210 | ij_javascript_var_declaration_wrap = normal 211 | ij_javascript_while_brace_force = never 212 | ij_javascript_while_on_new_line = false 213 | ij_javascript_wrap_comments = false 214 | 215 | [{*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.prettierrc,.stylelintrc,bowerrc,jest.config}] 216 | indent_size = 2 217 | ij_json_array_wrapping = split_into_lines 218 | ij_json_keep_blank_lines_in_code = 0 219 | ij_json_keep_indents_on_empty_lines = false 220 | ij_json_keep_line_breaks = true 221 | ij_json_keep_trailing_comma = false 222 | ij_json_object_wrapping = split_into_lines 223 | ij_json_property_alignment = do_not_align 224 | ij_json_space_after_colon = true 225 | ij_json_space_after_comma = true 226 | ij_json_space_before_colon = false 227 | ij_json_space_before_comma = false 228 | ij_json_spaces_within_braces = false 229 | ij_json_spaces_within_brackets = false 230 | ij_json_wrap_long_lines = false 231 | 232 | [{*.htm,*.html,*.sht,*.shtm,*.shtml}] 233 | ij_html_add_new_line_before_tags = body, div, p, form, h1, h2, h3 234 | ij_html_align_attributes = true 235 | ij_html_align_text = false 236 | ij_html_attribute_wrap = normal 237 | ij_html_block_comment_add_space = false 238 | ij_html_block_comment_at_first_column = true 239 | ij_html_do_not_align_children_of_min_lines = 0 240 | ij_html_do_not_break_if_inline_tags = title, h1, h2, h3, h4, h5, h6, p 241 | ij_html_do_not_indent_children_of_tags = html, body, thead, tbody, tfoot 242 | ij_html_enforce_quotes = false 243 | ij_html_inline_tags = a, abbr, acronym, b, basefont, bdo, big, br, cite, cite, code, dfn, em, font, i, img, input, kbd, label, q, s, samp, select, small, span, strike, strong, sub, sup, textarea, tt, u, var 244 | ij_html_keep_blank_lines = 2 245 | ij_html_keep_indents_on_empty_lines = false 246 | ij_html_keep_line_breaks = true 247 | ij_html_keep_line_breaks_in_text = true 248 | ij_html_keep_whitespaces = false 249 | ij_html_keep_whitespaces_inside = span, pre, textarea 250 | ij_html_line_comment_at_first_column = true 251 | ij_html_new_line_after_last_attribute = never 252 | ij_html_new_line_before_first_attribute = never 253 | ij_html_quote_style = double 254 | ij_html_remove_new_line_before_tags = br 255 | ij_html_space_after_tag_name = false 256 | ij_html_space_around_equality_in_attribute = false 257 | ij_html_space_inside_empty_tag = false 258 | ij_html_text_wrap = normal 259 | 260 | [{*.http,*.rest}] 261 | indent_size = 0 262 | ij_continuation_indent_size = 4 263 | 264 | [{*.markdown,*.md}] 265 | ij_markdown_force_one_space_after_blockquote_symbol = true 266 | ij_markdown_force_one_space_after_header_symbol = true 267 | ij_markdown_force_one_space_after_list_bullet = true 268 | ij_markdown_force_one_space_between_words = true 269 | ij_markdown_format_tables = true 270 | ij_markdown_insert_quote_arrows_on_wrap = true 271 | ij_markdown_keep_indents_on_empty_lines = false 272 | ij_markdown_keep_line_breaks_inside_text_blocks = true 273 | ij_markdown_max_lines_around_block_elements = 1 274 | ij_markdown_max_lines_around_header = 1 275 | ij_markdown_max_lines_between_paragraphs = 1 276 | ij_markdown_min_lines_around_block_elements = 1 277 | ij_markdown_min_lines_around_header = 1 278 | ij_markdown_min_lines_between_paragraphs = 1 279 | ij_markdown_wrap_text_if_long = true 280 | ij_markdown_wrap_text_inside_blockquotes = true 281 | --------------------------------------------------------------------------------