19 | Swapping to the Development environment displays detailed information about the error that occurred.
20 |
21 |
22 | The Development environment shouldn't be enabled for deployed applications.
23 | It can result in displaying sensitive information from exceptions to end users.
24 | For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development
25 | and restarting the app.
26 |
27 |
--------------------------------------------------------------------------------
/DotNetSyntaxTreeVisualizer/Pages/Error.cshtml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 | using Microsoft.AspNetCore.Mvc;
7 | using Microsoft.AspNetCore.Mvc.RazorPages;
8 | using Microsoft.Extensions.Logging;
9 |
10 | namespace DotNetSyntaxTreeVisualizer.Pages
11 | {
12 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
13 | public class ErrorModel : PageModel
14 | {
15 | private readonly ILogger _logger;
16 |
17 | public ErrorModel(ILogger logger)
18 | {
19 | _logger = logger;
20 | }
21 |
22 | public string RequestId { get; set; }
23 |
24 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
25 |
26 | public void OnGet()
27 | {
28 | RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/azure-pipelines.yml:
--------------------------------------------------------------------------------
1 | # ASP.NET
2 | # Build and test ASP.NET projects.
3 | # Add steps that publish symbols, save build artifacts, deploy, and more:
4 | # https://docs.microsoft.com/azure/devops/pipelines/apps/aspnet/build-aspnet-4
5 |
6 | trigger:
7 | - main
8 |
9 | pool:
10 | vmImage: 'windows-latest'
11 |
12 | variables:
13 | solution: '**/*.sln'
14 | buildPlatform: 'Any CPU'
15 | buildConfiguration: 'Release'
16 |
17 | steps:
18 | - task: NuGetToolInstaller@1
19 |
20 | - task: NuGetCommand@2
21 | inputs:
22 | restoreSolution: '$(solution)'
23 |
24 | - task: VSBuild@1
25 | inputs:
26 | solution: '$(solution)'
27 | msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactStagingDirectory)"'
28 | platform: '$(buildPlatform)'
29 | configuration: '$(buildConfiguration)'
30 |
31 | - task: VSTest@2
32 | inputs:
33 | platform: '$(buildPlatform)'
34 | configuration: '$(buildConfiguration)'
35 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DotNetSyntaxTreeVisualizer
2 |
3 | .NET Syntax Tree Visualizer, A C# ASP.NET Core app with ReactJS in front-end that shows Roslyn's syntax tree for a given source code.
4 |
5 | The app is deployed [here](https://DotNetSyntaxTreeVisualizer.azurewebsites.net/). If you encountered any problems, do a hard refresh using Ctrl+F5 from your browser.
6 |
7 | ## Visual Studio already has a graph visualizer
8 |
9 | That's true. But not all developers work on Visual Studio. Some developers might be using Rider, VS Code, or whatever. Or you might just be lazy to open Visual Studio!
10 |
11 | ## Why to inspect a syntax tree
12 |
13 | - For fun, if you just want to see what's the syntax tree Roslyn is generating.
14 | - For writing Roslyn's analyzers and codefixes requies knowledge of how the syntax tree for the case you're inspecting looks like.
15 |
16 | ## Screenshot
17 |
18 | 
19 |
20 | ## Features
21 |
22 | ### Current features
23 |
24 | - Collapsing and expanding a node.
25 | - Zooming
26 |
27 | ### TODO
28 |
29 | - Support Visual Basic [#6](https://github.com/Youssef1313/DotNetSyntaxTreeVisualizer/issues/6).
30 | - Allow sharing snippets [#9](https://github.com/Youssef1313/DotNetSyntaxTreeVisualizer/issues/9).
31 | - Add Syntax Highlighting [#4](https://github.com/Youssef1313/DotNetSyntaxTreeVisualizer/issues/4).
32 |
--------------------------------------------------------------------------------
/DotNetSyntaxTreeVisualizer/ClientApp/src/components/NavMenu.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { Collapse, Container, Navbar, NavbarBrand, NavbarToggler, NavItem, NavLink } from 'reactstrap';
3 | import { Link } from 'react-router-dom';
4 | import './NavMenu.css';
5 |
6 | export class NavMenu extends Component {
7 | static displayName = NavMenu.name;
8 |
9 | constructor (props) {
10 | super(props);
11 |
12 | this.toggleNavbar = this.toggleNavbar.bind(this);
13 | this.state = {
14 | collapsed: true
15 | };
16 | }
17 |
18 | toggleNavbar () {
19 | this.setState({
20 | collapsed: !this.state.collapsed
21 | });
22 | }
23 |
24 | render () {
25 | return (
26 |
27 |
28 |
29 | DotNetSyntaxTreeVisualizer
30 |
31 |
32 |
54 |
55 | );
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/DotNetSyntaxTreeVisualizer/Controllers/SyntaxTreeController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Reflection;
5 | using System.Text;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 | using Microsoft.AspNetCore.Mvc;
9 | using Microsoft.CodeAnalysis;
10 | using Microsoft.CodeAnalysis.CSharp;
11 | using Microsoft.CodeAnalysis.VisualBasic;
12 | using Microsoft.Extensions.Logging;
13 |
14 | namespace DotNetSyntaxTreeVisualizer.Controllers
15 | {
16 | [ApiController]
17 | [Route("[controller]")]
18 | public class SyntaxTreeController : ControllerBase
19 | {
20 | private readonly ILogger _logger;
21 |
22 | public SyntaxTreeController(ILogger logger)
23 | {
24 | _logger = logger;
25 | }
26 |
27 | [HttpPost("CSharp")] // POST: /SyntaxTree/CSharp
28 | public async Task CSharpPost(CancellationToken cancellationToken)
29 | {
30 | using var reader = new StreamReader(Request.Body, Encoding.UTF8);
31 | string body = await reader.ReadToEndAsync().ConfigureAwait(false);
32 | SyntaxTree tree = CSharpSyntaxTree.ParseText(body);
33 | SyntaxNode root = await tree.GetRootAsync(cancellationToken).ConfigureAwait(false);
34 | Compilation compilation = CSharpCompilation.Create("HelloWorld", new[] { tree });
35 | SemanticModel model = compilation.GetSemanticModel(tree);
36 | SyntaxTreeNode myRoot = SyntaxTreeNode.CreateMyOwnTree(root, model);
37 | return myRoot;
38 | }
39 |
40 | [HttpPost("VisualBasic")] // POST: /SyntaxTree/VisualBasic
41 | public async Task VisualBasicPost(CancellationToken cancellationToken)
42 | {
43 | using var reader = new StreamReader(Request.Body, Encoding.UTF8);
44 | string body = await reader.ReadToEndAsync().ConfigureAwait(false);
45 | SyntaxTree tree = VisualBasicSyntaxTree.ParseText(body);
46 | SyntaxNode root = await tree.GetRootAsync(cancellationToken).ConfigureAwait(false);
47 | Compilation compilation = VisualBasicCompilation.Create("HelloWorld", new[] { tree });
48 | SemanticModel model = compilation.GetSemanticModel(tree);
49 | SyntaxTreeNode myRoot = SyntaxTreeNode.CreateMyOwnTree(root, model);
50 | return myRoot;
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/DotNetSyntaxTreeVisualizer/Startup.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Builder;
2 | using Microsoft.AspNetCore.Hosting;
3 | using Microsoft.AspNetCore.HttpsPolicy;
4 | using Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer;
5 | using Microsoft.Extensions.Configuration;
6 | using Microsoft.Extensions.DependencyInjection;
7 | using Microsoft.Extensions.Hosting;
8 |
9 | namespace DotNetSyntaxTreeVisualizer
10 | {
11 | public class Startup
12 | {
13 | public Startup(IConfiguration configuration)
14 | {
15 | Configuration = configuration;
16 | }
17 |
18 | public IConfiguration Configuration { get; }
19 |
20 | // This method gets called by the runtime. Use this method to add services to the container.
21 | public void ConfigureServices(IServiceCollection services)
22 | {
23 |
24 | services.AddControllersWithViews();
25 |
26 | // In production, the React files will be served from this directory
27 | services.AddSpaStaticFiles(configuration =>
28 | {
29 | configuration.RootPath = "ClientApp/build";
30 | });
31 | }
32 |
33 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
34 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
35 | {
36 | if (env.IsDevelopment())
37 | {
38 | app.UseDeveloperExceptionPage();
39 | }
40 | else
41 | {
42 | app.UseExceptionHandler("/Error");
43 | // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
44 | app.UseHsts();
45 | }
46 |
47 | app.UseHttpsRedirection();
48 | app.UseStaticFiles();
49 | app.UseSpaStaticFiles();
50 |
51 | app.UseRouting();
52 |
53 | app.UseEndpoints(endpoints =>
54 | {
55 | endpoints.MapControllerRoute(
56 | name: "default",
57 | pattern: "{controller}/{action=Index}/{id?}");
58 | });
59 |
60 | app.UseSpa(spa =>
61 | {
62 | spa.Options.SourcePath = "ClientApp";
63 |
64 | if (env.IsDevelopment())
65 | {
66 | spa.UseReactDevelopmentServer(npmScript: "start");
67 | }
68 | });
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/DotNetSyntaxTreeVisualizer/DotNetSyntaxTreeVisualizer.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 | true
6 | Latest
7 | false
8 | ClientApp\
9 | $(DefaultItemExcludes);$(SpaRoot)node_modules\**
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 | %(DistFiles.Identity)
45 | PreserveNewest
46 | true
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/DotNetSyntaxTreeVisualizer/SyntaxTreeNode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 | using Microsoft.CodeAnalysis;
6 |
7 | namespace DotNetSyntaxTreeVisualizer
8 | {
9 | [Serializable]
10 | public class SyntaxTreeNode
11 | {
12 | public string Name { get; }
13 |
14 | public IDictionary Properties { get; }
15 | public IList Children { get; } = new List();
16 |
17 | public SyntaxTreeNode(IDictionary properties) =>
18 | (Properties, Name) = (properties, properties.Values.First());
19 |
20 | public void AddChild(SyntaxTreeNode child)
21 | {
22 | Children.Add(child);
23 | }
24 |
25 | public static SyntaxTreeNode CreateMyOwnTree(SyntaxNodeOrToken nodeOrToken, SemanticModel model)
26 | {
27 | var root = new SyntaxTreeNode(GetSyntaxInformation(nodeOrToken, model));
28 | foreach (SyntaxNodeOrToken child in nodeOrToken.ChildNodesAndTokens())
29 | {
30 | root.AddChild(CreateMyOwnTree(child, model));
31 | }
32 | return root;
33 | }
34 |
35 | private static IDictionary GetSyntaxInformation(SyntaxNodeOrToken syntax, SemanticModel model)
36 | {
37 | Func csharpKind = Microsoft.CodeAnalysis.CSharp.CSharpExtensions.Kind;
38 | Func vbKind = Microsoft.CodeAnalysis.VisualBasic.VisualBasicExtensions.Kind;
39 | string kind =
40 | syntax.Language == LanguageNames.CSharp
41 | ? csharpKind(syntax).ToString()
42 | : vbKind(syntax).ToString();
43 |
44 | var result = new Dictionary
45 | {
46 | { "Kind", kind },
47 | };
48 |
49 | IOperation operation = model.GetOperation(syntax.AsNode());
50 | if (operation is object)
51 | {
52 | result.Add(nameof(IOperation), operation.Kind.ToString());
53 | }
54 |
55 | PropertyInfo[] properties = syntax.GetType().GetProperties();
56 | foreach (PropertyInfo info in properties)
57 | {
58 | // Language isn't important to include in each node.
59 | // Parent is redundant. I can already see the parent.
60 | // ValueText and Value are the same as Text.
61 | // SyntaxTree shows the complete source in each node. That's redundant.
62 | // RawKind is just the underlying numeric value of SyntaxKind enum. It's meaningless.
63 | if (info.Name == "Language" || info.Name == "Parent" ||
64 | info.Name == "ValueText" || info.Name == "Value" ||
65 | info.Name == "SyntaxTree" || info.Name == "RawKind")
66 | {
67 | continue;
68 | }
69 | result.Add(info.Name, info.GetValue(syntax)?.ToString());
70 | }
71 | return result;
72 | }
73 |
74 | public override string ToString()
75 | {
76 | return Properties.Values.First();
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/DotNetSyntaxTreeVisualizer/ClientApp/src/registerServiceWorker.js:
--------------------------------------------------------------------------------
1 | // In production, we register a service worker to serve assets from local cache.
2 |
3 | // This lets the app load faster on subsequent visits in production, and gives
4 | // it offline capabilities. However, it also means that developers (and users)
5 | // will only see deployed updates on the "N+1" visit to a page, since previously
6 | // cached resources are updated in the background.
7 |
8 | // To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
9 | // This link also includes instructions on opting out of this behavior.
10 |
11 | const isLocalhost = Boolean(
12 | window.location.hostname === 'localhost' ||
13 | // [::1] is the IPv6 localhost address.
14 | window.location.hostname === '[::1]' ||
15 | // 127.0.0.1/8 is considered localhost for IPv4.
16 | window.location.hostname.match(
17 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
18 | )
19 | );
20 |
21 | export default function register () {
22 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
23 | // The URL constructor is available in all browsers that support SW.
24 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
25 | if (publicUrl.origin !== window.location.origin) {
26 | // Our service worker won't work if PUBLIC_URL is on a different origin
27 | // from what our page is served on. This might happen if a CDN is used to
28 | // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
29 | return;
30 | }
31 |
32 | window.addEventListener('load', () => {
33 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
34 |
35 | if (isLocalhost) {
36 | // This is running on localhost. Lets check if a service worker still exists or not.
37 | checkValidServiceWorker(swUrl);
38 | } else {
39 | // Is not local host. Just register service worker
40 | registerValidSW(swUrl);
41 | }
42 | });
43 | }
44 | }
45 |
46 | function registerValidSW (swUrl) {
47 | navigator.serviceWorker
48 | .register(swUrl)
49 | .then(registration => {
50 | registration.onupdatefound = () => {
51 | const installingWorker = registration.installing;
52 | installingWorker.onstatechange = () => {
53 | if (installingWorker.state === 'installed') {
54 | if (navigator.serviceWorker.controller) {
55 | // At this point, the old content will have been purged and
56 | // the fresh content will have been added to the cache.
57 | // It's the perfect time to display a "New content is
58 | // available; please refresh." message in your web app.
59 | console.log('New content is available; please refresh.');
60 | } else {
61 | // At this point, everything has been precached.
62 | // It's the perfect time to display a
63 | // "Content is cached for offline use." message.
64 | console.log('Content is cached for offline use.');
65 | }
66 | }
67 | };
68 | };
69 | })
70 | .catch(error => {
71 | console.error('Error during service worker registration:', error);
72 | });
73 | }
74 |
75 | function checkValidServiceWorker (swUrl) {
76 | // Check if the service worker can be found. If it can't reload the page.
77 | fetch(swUrl)
78 | .then(response => {
79 | // Ensure service worker exists, and that we really are getting a JS file.
80 | if (
81 | response.status === 404 ||
82 | response.headers.get('content-type').indexOf('javascript') === -1
83 | ) {
84 | // No service worker found. Probably a different app. Reload the page.
85 | navigator.serviceWorker.ready.then(registration => {
86 | registration.unregister().then(() => {
87 | window.location.reload();
88 | });
89 | });
90 | } else {
91 | // Service worker found. Proceed as normal.
92 | registerValidSW(swUrl);
93 | }
94 | })
95 | .catch(() => {
96 | console.log(
97 | 'No internet connection found. App is running in offline mode.'
98 | );
99 | });
100 | }
101 |
102 | export function unregister () {
103 | if ('serviceWorker' in navigator) {
104 | navigator.serviceWorker.ready.then(registration => {
105 | registration.unregister();
106 | });
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/DotNetSyntaxTreeVisualizer/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | build/
21 | bld/
22 | bin/
23 | Bin/
24 | obj/
25 | Obj/
26 |
27 | # Visual Studio 2015 cache/options directory
28 | .vs/
29 | /wwwroot/dist/
30 |
31 | # MSTest test Results
32 | [Tt]est[Rr]esult*/
33 | [Bb]uild[Ll]og.*
34 |
35 | # NUNIT
36 | *.VisualState.xml
37 | TestResult.xml
38 |
39 | # Build Results of an ATL Project
40 | [Dd]ebugPS/
41 | [Rr]eleasePS/
42 | dlldata.c
43 |
44 | *_i.c
45 | *_p.c
46 | *_i.h
47 | *.ilk
48 | *.meta
49 | *.obj
50 | *.pch
51 | *.pdb
52 | *.pgc
53 | *.pgd
54 | *.rsp
55 | *.sbr
56 | *.tlb
57 | *.tli
58 | *.tlh
59 | *.tmp
60 | *.tmp_proj
61 | *.log
62 | *.vspscc
63 | *.vssscc
64 | .builds
65 | *.pidb
66 | *.svclog
67 | *.scc
68 |
69 | # Chutzpah Test files
70 | _Chutzpah*
71 |
72 | # Visual C++ cache files
73 | ipch/
74 | *.aps
75 | *.ncb
76 | *.opendb
77 | *.opensdf
78 | *.sdf
79 | *.cachefile
80 |
81 | # Visual Studio profiler
82 | *.psess
83 | *.vsp
84 | *.vspx
85 | *.sap
86 |
87 | # TFS 2012 Local Workspace
88 | $tf/
89 |
90 | # Guidance Automation Toolkit
91 | *.gpState
92 |
93 | # ReSharper is a .NET coding add-in
94 | _ReSharper*/
95 | *.[Rr]e[Ss]harper
96 | *.DotSettings.user
97 |
98 | # JustCode is a .NET coding add-in
99 | .JustCode
100 |
101 | # TeamCity is a build add-in
102 | _TeamCity*
103 |
104 | # DotCover is a Code Coverage Tool
105 | *.dotCover
106 |
107 | # NCrunch
108 | _NCrunch_*
109 | .*crunch*.local.xml
110 | nCrunchTemp_*
111 |
112 | # MightyMoose
113 | *.mm.*
114 | AutoTest.Net/
115 |
116 | # Web workbench (sass)
117 | .sass-cache/
118 |
119 | # Installshield output folder
120 | [Ee]xpress/
121 |
122 | # DocProject is a documentation generator add-in
123 | DocProject/buildhelp/
124 | DocProject/Help/*.HxT
125 | DocProject/Help/*.HxC
126 | DocProject/Help/*.hhc
127 | DocProject/Help/*.hhk
128 | DocProject/Help/*.hhp
129 | DocProject/Help/Html2
130 | DocProject/Help/html
131 |
132 | # Click-Once directory
133 | publish/
134 |
135 | # Publish Web Output
136 | *.[Pp]ublish.xml
137 | *.azurePubxml
138 | # TODO: Comment the next line if you want to checkin your web deploy settings
139 | # but database connection strings (with potential passwords) will be unencrypted
140 | *.pubxml
141 | *.publishproj
142 |
143 | # NuGet Packages
144 | *.nupkg
145 | # The packages folder can be ignored because of Package Restore
146 | **/packages/*
147 | # except build/, which is used as an MSBuild target.
148 | !**/packages/build/
149 | # Uncomment if necessary however generally it will be regenerated when needed
150 | #!**/packages/repositories.config
151 |
152 | # Microsoft Azure Build Output
153 | csx/
154 | *.build.csdef
155 |
156 | # Microsoft Azure Emulator
157 | ecf/
158 | rcf/
159 |
160 | # Microsoft Azure ApplicationInsights config file
161 | ApplicationInsights.config
162 |
163 | # Windows Store app package directory
164 | AppPackages/
165 | BundleArtifacts/
166 |
167 | # Visual Studio cache files
168 | # files ending in .cache can be ignored
169 | *.[Cc]ache
170 | # but keep track of directories ending in .cache
171 | !*.[Cc]ache/
172 |
173 | # Others
174 | ClientBin/
175 | ~$*
176 | *~
177 | *.dbmdl
178 | *.dbproj.schemaview
179 | *.pfx
180 | *.publishsettings
181 | orleans.codegen.cs
182 |
183 | /node_modules
184 |
185 | # RIA/Silverlight projects
186 | Generated_Code/
187 |
188 | # Backup & report files from converting an old project file
189 | # to a newer Visual Studio version. Backup files are not needed,
190 | # because we have git ;-)
191 | _UpgradeReport_Files/
192 | Backup*/
193 | UpgradeLog*.XML
194 | UpgradeLog*.htm
195 |
196 | # SQL Server files
197 | *.mdf
198 | *.ldf
199 |
200 | # Business Intelligence projects
201 | *.rdl.data
202 | *.bim.layout
203 | *.bim_*.settings
204 |
205 | # Microsoft Fakes
206 | FakesAssemblies/
207 |
208 | # GhostDoc plugin setting file
209 | *.GhostDoc.xml
210 |
211 | # Node.js Tools for Visual Studio
212 | .ntvs_analysis.dat
213 |
214 | # Visual Studio 6 build log
215 | *.plg
216 |
217 | # Visual Studio 6 workspace options file
218 | *.opt
219 |
220 | # Visual Studio LightSwitch build output
221 | **/*.HTMLClient/GeneratedArtifacts
222 | **/*.DesktopClient/GeneratedArtifacts
223 | **/*.DesktopClient/ModelManifest.xml
224 | **/*.Server/GeneratedArtifacts
225 | **/*.Server/ModelManifest.xml
226 | _Pvt_Extensions
227 |
228 | # Paket dependency manager
229 | .paket/paket.exe
230 |
231 | # FAKE - F# Make
232 | .fake/
233 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Build results
17 | [Dd]ebug/
18 | [Dd]ebugPublic/
19 | [Rr]elease/
20 | [Rr]eleases/
21 | x64/
22 | x86/
23 | [Aa][Rr][Mm]/
24 | [Aa][Rr][Mm]64/
25 | bld/
26 | [Bb]in/
27 | [Oo]bj/
28 | [Ll]og/
29 |
30 | # Visual Studio 2015/2017 cache/options directory
31 | .vs/
32 | # Uncomment if you have tasks that create the project's static files in wwwroot
33 | #wwwroot/
34 |
35 | # Visual Studio 2017 auto generated files
36 | Generated\ Files/
37 |
38 | # MSTest test Results
39 | [Tt]est[Rr]esult*/
40 | [Bb]uild[Ll]og.*
41 |
42 | # NUNIT
43 | *.VisualState.xml
44 | TestResult.xml
45 |
46 | # Build Results of an ATL Project
47 | [Dd]ebugPS/
48 | [Rr]eleasePS/
49 | dlldata.c
50 |
51 | # Benchmark Results
52 | BenchmarkDotNet.Artifacts/
53 |
54 | # .NET Core
55 | project.lock.json
56 | project.fragment.lock.json
57 | artifacts/
58 |
59 | # StyleCop
60 | StyleCopReport.xml
61 |
62 | # Files built by Visual Studio
63 | *_i.c
64 | *_p.c
65 | *_h.h
66 | *.ilk
67 | *.meta
68 | *.obj
69 | *.iobj
70 | *.pch
71 | *.pdb
72 | *.ipdb
73 | *.pgc
74 | *.pgd
75 | *.rsp
76 | *.sbr
77 | *.tlb
78 | *.tli
79 | *.tlh
80 | *.tmp
81 | *.tmp_proj
82 | *_wpftmp.csproj
83 | *.log
84 | *.vspscc
85 | *.vssscc
86 | .builds
87 | *.pidb
88 | *.svclog
89 | *.scc
90 |
91 | # Chutzpah Test files
92 | _Chutzpah*
93 |
94 | # Visual C++ cache files
95 | ipch/
96 | *.aps
97 | *.ncb
98 | *.opendb
99 | *.opensdf
100 | *.sdf
101 | *.cachefile
102 | *.VC.db
103 | *.VC.VC.opendb
104 |
105 | # Visual Studio profiler
106 | *.psess
107 | *.vsp
108 | *.vspx
109 | *.sap
110 |
111 | # Visual Studio Trace Files
112 | *.e2e
113 |
114 | # TFS 2012 Local Workspace
115 | $tf/
116 |
117 | # Guidance Automation Toolkit
118 | *.gpState
119 |
120 | # ReSharper is a .NET coding add-in
121 | _ReSharper*/
122 | *.[Rr]e[Ss]harper
123 | *.DotSettings.user
124 |
125 | # JustCode is a .NET coding add-in
126 | .JustCode
127 |
128 | # TeamCity is a build add-in
129 | _TeamCity*
130 |
131 | # DotCover is a Code Coverage Tool
132 | *.dotCover
133 |
134 | # AxoCover is a Code Coverage Tool
135 | .axoCover/*
136 | !.axoCover/settings.json
137 |
138 | # Visual Studio code coverage results
139 | *.coverage
140 | *.coveragexml
141 |
142 | # NCrunch
143 | _NCrunch_*
144 | .*crunch*.local.xml
145 | nCrunchTemp_*
146 |
147 | # MightyMoose
148 | *.mm.*
149 | AutoTest.Net/
150 |
151 | # Web workbench (sass)
152 | .sass-cache/
153 |
154 | # Installshield output folder
155 | [Ee]xpress/
156 |
157 | # DocProject is a documentation generator add-in
158 | DocProject/buildhelp/
159 | DocProject/Help/*.HxT
160 | DocProject/Help/*.HxC
161 | DocProject/Help/*.hhc
162 | DocProject/Help/*.hhk
163 | DocProject/Help/*.hhp
164 | DocProject/Help/Html2
165 | DocProject/Help/html
166 |
167 | # Click-Once directory
168 | publish/
169 |
170 | # Publish Web Output
171 | *.[Pp]ublish.xml
172 | *.azurePubxml
173 | # Note: Comment the next line if you want to checkin your web deploy settings,
174 | # but database connection strings (with potential passwords) will be unencrypted
175 | *.pubxml
176 | *.publishproj
177 |
178 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
179 | # checkin your Azure Web App publish settings, but sensitive information contained
180 | # in these scripts will be unencrypted
181 | PublishScripts/
182 |
183 | # NuGet Packages
184 | *.nupkg
185 | # The packages folder can be ignored because of Package Restore
186 | **/[Pp]ackages/*
187 | # except build/, which is used as an MSBuild target.
188 | !**/[Pp]ackages/build/
189 | # Uncomment if necessary however generally it will be regenerated when needed
190 | #!**/[Pp]ackages/repositories.config
191 | # NuGet v3's project.json files produces more ignorable files
192 | *.nuget.props
193 | *.nuget.targets
194 |
195 | # Microsoft Azure Build Output
196 | csx/
197 | *.build.csdef
198 |
199 | # Microsoft Azure Emulator
200 | ecf/
201 | rcf/
202 |
203 | # Windows Store app package directories and files
204 | AppPackages/
205 | BundleArtifacts/
206 | Package.StoreAssociation.xml
207 | _pkginfo.txt
208 | *.appx
209 |
210 | # Visual Studio cache files
211 | # files ending in .cache can be ignored
212 | *.[Cc]ache
213 | # but keep track of directories ending in .cache
214 | !?*.[Cc]ache/
215 |
216 | # Others
217 | ClientBin/
218 | ~$*
219 | *~
220 | *.dbmdl
221 | *.dbproj.schemaview
222 | *.jfm
223 | *.pfx
224 | *.publishsettings
225 | orleans.codegen.cs
226 |
227 | # Including strong name files can present a security risk
228 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
229 | #*.snk
230 |
231 | # Since there are multiple workflows, uncomment next line to ignore bower_components
232 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
233 | #bower_components/
234 |
235 | # RIA/Silverlight projects
236 | Generated_Code/
237 |
238 | # Backup & report files from converting an old project file
239 | # to a newer Visual Studio version. Backup files are not needed,
240 | # because we have git ;-)
241 | _UpgradeReport_Files/
242 | Backup*/
243 | UpgradeLog*.XML
244 | UpgradeLog*.htm
245 | ServiceFabricBackup/
246 | *.rptproj.bak
247 |
248 | # SQL Server files
249 | *.mdf
250 | *.ldf
251 | *.ndf
252 |
253 | # Business Intelligence projects
254 | *.rdl.data
255 | *.bim.layout
256 | *.bim_*.settings
257 | *.rptproj.rsuser
258 | *- Backup*.rdl
259 |
260 | # Microsoft Fakes
261 | FakesAssemblies/
262 |
263 | # GhostDoc plugin setting file
264 | *.GhostDoc.xml
265 |
266 | # Node.js Tools for Visual Studio
267 | .ntvs_analysis.dat
268 | node_modules/
269 |
270 | # Visual Studio 6 build log
271 | *.plg
272 |
273 | # Visual Studio 6 workspace options file
274 | *.opt
275 |
276 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
277 | *.vbw
278 |
279 | # Visual Studio LightSwitch build output
280 | **/*.HTMLClient/GeneratedArtifacts
281 | **/*.DesktopClient/GeneratedArtifacts
282 | **/*.DesktopClient/ModelManifest.xml
283 | **/*.Server/GeneratedArtifacts
284 | **/*.Server/ModelManifest.xml
285 | _Pvt_Extensions
286 |
287 | # Paket dependency manager
288 | .paket/paket.exe
289 | paket-files/
290 |
291 | # FAKE - F# Make
292 | .fake/
293 |
294 | # JetBrains Rider
295 | .idea/
296 | *.sln.iml
297 |
298 | # CodeRush personal settings
299 | .cr/personal
300 |
301 | # Python Tools for Visual Studio (PTVS)
302 | __pycache__/
303 | *.pyc
304 |
305 | # Cake - Uncomment if you are using it
306 | # tools/**
307 | # !tools/packages.config
308 |
309 | # Tabs Studio
310 | *.tss
311 |
312 | # Telerik's JustMock configuration file
313 | *.jmconfig
314 |
315 | # BizTalk build output
316 | *.btp.cs
317 | *.btm.cs
318 | *.odx.cs
319 | *.xsd.cs
320 |
321 | # OpenCover UI analysis results
322 | OpenCover/
323 |
324 | # Azure Stream Analytics local run output
325 | ASALocalRun/
326 |
327 | # MSBuild Binary and Structured Log
328 | *.binlog
329 |
330 | # NVidia Nsight GPU debugger configuration file
331 | *.nvuser
332 |
333 | # MFractors (Xamarin productivity tool) working folder
334 | .mfractor/
335 |
336 | # Local History for Visual Studio
337 | .localhistory/
338 |
339 | # BeatPulse healthcheck temp database
340 | healthchecksdb
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # Remove the line below if you want to inherit .editorconfig settings from higher directories
2 | root = true
3 |
4 | [*]
5 | insert_final_newline = true
6 | indent_style = space
7 | trim_trailing_whitespace = true
8 |
9 | # C# files
10 | [*.cs]
11 |
12 | # Indentation and spacing
13 | indent_size = 4
14 |
15 | # New line preferences
16 | csharp_new_line_before_catch = true
17 | csharp_new_line_before_else = true
18 | csharp_new_line_before_finally = true
19 | csharp_new_line_before_members_in_anonymous_types = true
20 | csharp_new_line_before_members_in_object_initializers = true
21 | csharp_new_line_before_open_brace = all
22 | csharp_new_line_between_query_expression_clauses = true
23 |
24 | # Indentation preferences
25 | csharp_indent_block_contents = true
26 | csharp_indent_braces = false
27 | csharp_indent_case_contents = true
28 | csharp_indent_case_contents_when_block = true
29 | csharp_indent_labels = one_less_than_current
30 | csharp_indent_switch_labels = true
31 |
32 | # Modifier preferences
33 | csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
34 |
35 | # this. and Me. preferences
36 | dotnet_style_qualification_for_event = false:suggestion
37 | dotnet_style_qualification_for_field = false:suggestion
38 | dotnet_style_qualification_for_method = false:suggestion
39 | dotnet_style_qualification_for_property = false:suggestion
40 |
41 | # var preferences
42 | csharp_style_var_for_built_in_types = false:suggestion
43 | csharp_style_var_when_type_is_apparent = true:suggestion
44 | csharp_style_var_elsewhere = false:suggestion
45 |
46 | # Language keywords vs BCL types preferences
47 | dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
48 | dotnet_style_predefined_type_for_member_access = true:suggestion
49 |
50 | # Naming rules
51 | dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
52 | dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
53 | dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
54 |
55 | dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
56 | dotnet_naming_rule.types_should_be_pascal_case.symbols = types
57 | dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
58 |
59 | dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
60 | dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
61 | dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
62 |
63 | # name all constant fields using PascalCase
64 | dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
65 | dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
66 | dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
67 | dotnet_naming_symbols.constant_fields.applicable_kinds = field
68 | dotnet_naming_symbols.constant_fields.required_modifiers = const
69 | dotnet_naming_style.pascal_case_style.capitalization = pascal_case
70 |
71 | # static fields should have s_ prefix
72 | dotnet_naming_rule.static_fields_should_have_prefix.severity = suggestion
73 | dotnet_naming_rule.static_fields_should_have_prefix.symbols = static_fields
74 | dotnet_naming_rule.static_fields_should_have_prefix.style = static_prefix_style
75 | dotnet_naming_symbols.static_fields.applicable_kinds = field
76 | dotnet_naming_symbols.static_fields.required_modifiers = static
77 | dotnet_naming_symbols.static_fields.applicable_accessibilities = private, internal, private_protected
78 | dotnet_naming_style.static_prefix_style.required_prefix = s_
79 | dotnet_naming_style.static_prefix_style.capitalization = camel_case
80 |
81 | # internal and private fields should be _camelCase
82 | dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion
83 | dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields
84 | dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style
85 | dotnet_naming_symbols.private_internal_fields.applicable_kinds = field
86 | dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal
87 | dotnet_naming_style.camel_case_underscore_style.required_prefix = _
88 | dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case
89 |
90 | dotnet_naming_symbols.interface.applicable_kinds = interface
91 | dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
92 | dotnet_naming_symbols.interface.required_modifiers =
93 |
94 | dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
95 | dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
96 | dotnet_naming_symbols.types.required_modifiers =
97 |
98 | dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
99 | dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
100 | dotnet_naming_symbols.non_field_members.required_modifiers =
101 |
102 | # Code style defaults
103 | csharp_using_directive_placement = outside_namespace:suggestion
104 | dotnet_sort_system_directives_first = true
105 | csharp_prefer_braces = true:silent
106 | csharp_preserve_single_line_blocks = true:none
107 | csharp_preserve_single_line_statements = false:none
108 | csharp_prefer_static_local_function = true:suggestion
109 | csharp_prefer_simple_using_statement = true:suggestion
110 | csharp_style_prefer_switch_expression = true:suggestion
111 |
112 | # Code quality
113 | dotnet_style_readonly_field = true:suggestion
114 | dotnet_code_quality_unused_parameters = all:suggestion
115 |
116 | # Expression-level preferences
117 | dotnet_style_coalesce_expression = true:suggestion
118 | dotnet_style_collection_initializer = true:suggestion
119 | dotnet_style_explicit_tuple_names = true:suggestion
120 | dotnet_style_null_propagation = true:suggestion
121 | dotnet_style_object_initializer = true:suggestion
122 | dotnet_style_prefer_auto_properties = true:suggestion
123 | dotnet_style_prefer_compound_assignment = true:suggestion
124 | dotnet_style_prefer_conditional_expression_over_assignment = true:silent
125 | dotnet_style_prefer_conditional_expression_over_return = true:silent
126 | dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
127 | dotnet_style_prefer_inferred_tuple_names = true:suggestion
128 | dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
129 | dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
130 | dotnet_style_prefer_simplified_interpolation = true:suggestions
131 | csharp_prefer_simple_default_expression = true:suggestion
132 |
133 | # Expression-bodied members
134 | csharp_style_expression_bodied_accessors = true:silent
135 | csharp_style_expression_bodied_constructors = true:silent
136 | csharp_style_expression_bodied_indexers = true:silent
137 | csharp_style_expression_bodied_lambdas = true:silent
138 | csharp_style_expression_bodied_local_functions = true:silent
139 | csharp_style_expression_bodied_methods = true:silent
140 | csharp_style_expression_bodied_operators = true:silent
141 | csharp_style_expression_bodied_properties = true:silent
142 |
143 | # Pattern matching preferences
144 | csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
145 | csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
146 | csharp_style_prefer_switch_expression = true:suggestion
147 |
148 | # Null checking preferences
149 | csharp_style_throw_expression = true:suggestion
150 | csharp_style_conditional_delegate_call = true:suggestion
151 |
152 | # Space preferences
153 | csharp_space_after_cast = false
154 | csharp_space_after_colon_in_inheritance_clause = true
155 | csharp_space_after_comma = true
156 | csharp_space_after_dot = false
157 | csharp_space_after_keywords_in_control_flow_statements = true
158 | csharp_space_after_semicolon_in_for_statement = true
159 | csharp_space_around_binary_operators = before_and_after
160 | csharp_space_around_declaration_statements = false
161 | csharp_space_before_colon_in_inheritance_clause = true
162 | csharp_space_before_comma = false
163 | csharp_space_before_dot = false
164 | csharp_space_before_open_square_brackets = false
165 | csharp_space_before_semicolon_in_for_statement = false
166 | csharp_space_between_empty_square_brackets = false
167 | csharp_space_between_method_call_empty_parameter_list_parentheses = false
168 | csharp_space_between_method_call_name_and_opening_parenthesis = false
169 | csharp_space_between_method_call_parameter_list_parentheses = false
170 | csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
171 | csharp_space_between_method_declaration_name_and_open_parenthesis = false
172 | csharp_space_between_method_declaration_parameter_list_parentheses = false
173 | csharp_space_between_parentheses = false
174 | csharp_space_between_square_brackets = false
175 |
176 |
177 | # IDE0055: Fix formatting
178 | dotnet_diagnostic.IDE0055.severity = warning
179 |
180 |
181 | # Organize usings
182 | dotnet_separate_import_directive_groups = false
183 | file_header_template = unset
184 |
185 | # Parentheses preferences
186 | dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
187 | dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
188 | dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
189 | dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
190 |
191 | # Modifier preferences
192 | dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion
193 |
194 |
195 | # Expression-level preferences
196 | csharp_style_deconstructed_variable_declaration = true:suggestion
197 | csharp_style_inlined_variable_declaration = true:suggestion
198 | csharp_style_pattern_local_over_anonymous_function = true:suggestion
199 | csharp_style_prefer_index_operator = true:suggestion
200 | csharp_style_prefer_range_operator = true:suggestion
201 | csharp_style_unused_value_assignment_preference = discard_variable:suggestion
202 | csharp_style_unused_value_expression_statement_preference = discard_variable:silent
203 |
204 | # Naming styles
205 | dotnet_naming_style.pascal_case.required_prefix =
206 | dotnet_naming_style.pascal_case.required_suffix =
207 | dotnet_naming_style.pascal_case.word_separator =
208 | dotnet_naming_style.pascal_case.capitalization = pascal_case
209 |
210 | dotnet_naming_style.begins_with_i.required_prefix = I
211 | dotnet_naming_style.begins_with_i.required_suffix =
212 | dotnet_naming_style.begins_with_i.word_separator =
213 | dotnet_naming_style.begins_with_i.capitalization = pascal_case
214 |
--------------------------------------------------------------------------------
/DotNetSyntaxTreeVisualizer/ClientApp/README.md:
--------------------------------------------------------------------------------
1 | This project was bootstrapped with [Create React App](https://github.com/facebookincubator/create-react-app).
2 |
3 | Below you will find some information on how to perform common tasks.
4 | You can find the most recent version of this guide [here](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md).
5 |
6 | ## Table of Contents
7 |
8 | - [Updating to New Releases](#updating-to-new-releases)
9 | - [Sending Feedback](#sending-feedback)
10 | - [Folder Structure](#folder-structure)
11 | - [Available Scripts](#available-scripts)
12 | - [npm start](#npm-start)
13 | - [npm test](#npm-test)
14 | - [npm run build](#npm-run-build)
15 | - [npm run eject](#npm-run-eject)
16 | - [Supported Language Features and Polyfills](#supported-language-features-and-polyfills)
17 | - [Syntax Highlighting in the Editor](#syntax-highlighting-in-the-editor)
18 | - [Displaying Lint Output in the Editor](#displaying-lint-output-in-the-editor)
19 | - [Debugging in the Editor](#debugging-in-the-editor)
20 | - [Formatting Code Automatically](#formatting-code-automatically)
21 | - [Changing the Page ``](#changing-the-page-title)
22 | - [Installing a Dependency](#installing-a-dependency)
23 | - [Importing a Component](#importing-a-component)
24 | - [Code Splitting](#code-splitting)
25 | - [Adding a Stylesheet](#adding-a-stylesheet)
26 | - [Post-Processing CSS](#post-processing-css)
27 | - [Adding a CSS Preprocessor (Sass, Less etc.)](#adding-a-css-preprocessor-sass-less-etc)
28 | - [Adding Images, Fonts, and Files](#adding-images-fonts-and-files)
29 | - [Using the `public` Folder](#using-the-public-folder)
30 | - [Changing the HTML](#changing-the-html)
31 | - [Adding Assets Outside of the Module System](#adding-assets-outside-of-the-module-system)
32 | - [When to Use the `public` Folder](#when-to-use-the-public-folder)
33 | - [Using Global Variables](#using-global-variables)
34 | - [Adding Bootstrap](#adding-bootstrap)
35 | - [Using a Custom Theme](#using-a-custom-theme)
36 | - [Adding Flow](#adding-flow)
37 | - [Adding Custom Environment Variables](#adding-custom-environment-variables)
38 | - [Referencing Environment Variables in the HTML](#referencing-environment-variables-in-the-html)
39 | - [Adding Temporary Environment Variables In Your Shell](#adding-temporary-environment-variables-in-your-shell)
40 | - [Adding Development Environment Variables In `.env`](#adding-development-environment-variables-in-env)
41 | - [Can I Use Decorators?](#can-i-use-decorators)
42 | - [Integrating with an API Backend](#integrating-with-an-api-backend)
43 | - [Node](#node)
44 | - [Ruby on Rails](#ruby-on-rails)
45 | - [Proxying API Requests in Development](#proxying-api-requests-in-development)
46 | - ["Invalid Host Header" Errors After Configuring Proxy](#invalid-host-header-errors-after-configuring-proxy)
47 | - [Configuring the Proxy Manually](#configuring-the-proxy-manually)
48 | - [Configuring a WebSocket Proxy](#configuring-a-websocket-proxy)
49 | - [Using HTTPS in Development](#using-https-in-development)
50 | - [Generating Dynamic `` Tags on the Server](#generating-dynamic-meta-tags-on-the-server)
51 | - [Pre-Rendering into Static HTML Files](#pre-rendering-into-static-html-files)
52 | - [Injecting Data from the Server into the Page](#injecting-data-from-the-server-into-the-page)
53 | - [Running Tests](#running-tests)
54 | - [Filename Conventions](#filename-conventions)
55 | - [Command Line Interface](#command-line-interface)
56 | - [Version Control Integration](#version-control-integration)
57 | - [Writing Tests](#writing-tests)
58 | - [Testing Components](#testing-components)
59 | - [Using Third Party Assertion Libraries](#using-third-party-assertion-libraries)
60 | - [Initializing Test Environment](#initializing-test-environment)
61 | - [Focusing and Excluding Tests](#focusing-and-excluding-tests)
62 | - [Coverage Reporting](#coverage-reporting)
63 | - [Continuous Integration](#continuous-integration)
64 | - [Disabling jsdom](#disabling-jsdom)
65 | - [Snapshot Testing](#snapshot-testing)
66 | - [Editor Integration](#editor-integration)
67 | - [Developing Components in Isolation](#developing-components-in-isolation)
68 | - [Getting Started with Storybook](#getting-started-with-storybook)
69 | - [Getting Started with Styleguidist](#getting-started-with-styleguidist)
70 | - [Making a Progressive Web App](#making-a-progressive-web-app)
71 | - [Opting Out of Caching](#opting-out-of-caching)
72 | - [Offline-First Considerations](#offline-first-considerations)
73 | - [Progressive Web App Metadata](#progressive-web-app-metadata)
74 | - [Analyzing the Bundle Size](#analyzing-the-bundle-size)
75 | - [Deployment](#deployment)
76 | - [Static Server](#static-server)
77 | - [Other Solutions](#other-solutions)
78 | - [Serving Apps with Client-Side Routing](#serving-apps-with-client-side-routing)
79 | - [Building for Relative Paths](#building-for-relative-paths)
80 | - [Azure](#azure)
81 | - [Firebase](#firebase)
82 | - [GitHub Pages](#github-pages)
83 | - [Heroku](#heroku)
84 | - [Netlify](#netlify)
85 | - [Now](#now)
86 | - [S3 and CloudFront](#s3-and-cloudfront)
87 | - [Surge](#surge)
88 | - [Advanced Configuration](#advanced-configuration)
89 | - [Troubleshooting](#troubleshooting)
90 | - [`npm start` doesn’t detect changes](#npm-start-doesnt-detect-changes)
91 | - [`npm test` hangs on macOS Sierra](#npm-test-hangs-on-macos-sierra)
92 | - [`npm run build` exits too early](#npm-run-build-exits-too-early)
93 | - [`npm run build` fails on Heroku](#npm-run-build-fails-on-heroku)
94 | - [`npm run build` fails to minify](#npm-run-build-fails-to-minify)
95 | - [Moment.js locales are missing](#momentjs-locales-are-missing)
96 | - [Something Missing?](#something-missing)
97 |
98 | ## Updating to New Releases
99 |
100 | Create React App is divided into two packages:
101 |
102 | * `create-react-app` is a global command-line utility that you use to create new projects.
103 | * `react-scripts` is a development dependency in the generated projects (including this one).
104 |
105 | You almost never need to update `create-react-app` itself: it delegates all the setup to `react-scripts`.
106 |
107 | When you run `create-react-app`, it always creates the project with the latest version of `react-scripts` so you’ll get all the new features and improvements in newly created apps automatically.
108 |
109 | To update an existing project to a new version of `react-scripts`, [open the changelog](https://github.com/facebookincubator/create-react-app/blob/master/CHANGELOG.md), find the version you’re currently on (check `package.json` in this folder if you’re not sure), and apply the migration instructions for the newer versions.
110 |
111 | In most cases bumping the `react-scripts` version in `package.json` and running `npm install` in this folder should be enough, but it’s good to consult the [changelog](https://github.com/facebookincubator/create-react-app/blob/master/CHANGELOG.md) for potential breaking changes.
112 |
113 | We commit to keeping the breaking changes minimal so you can upgrade `react-scripts` painlessly.
114 |
115 | ## Sending Feedback
116 |
117 | We are always open to [your feedback](https://github.com/facebookincubator/create-react-app/issues).
118 |
119 | ## Folder Structure
120 |
121 | After creation, your project should look like this:
122 |
123 | ```
124 | my-app/
125 | README.md
126 | node_modules/
127 | package.json
128 | public/
129 | index.html
130 | favicon.ico
131 | src/
132 | App.css
133 | App.js
134 | App.test.js
135 | index.css
136 | index.js
137 | logo.svg
138 | ```
139 |
140 | For the project to build, **these files must exist with exact filenames**:
141 |
142 | * `public/index.html` is the page template;
143 | * `src/index.js` is the JavaScript entry point.
144 |
145 | You can delete or rename the other files.
146 |
147 | You may create subdirectories inside `src`. For faster rebuilds, only files inside `src` are processed by Webpack.
148 | You need to **put any JS and CSS files inside `src`**, otherwise Webpack won’t see them.
149 |
150 | Only files inside `public` can be used from `public/index.html`.
151 | Read instructions below for using assets from JavaScript and HTML.
152 |
153 | You can, however, create more top-level directories.
154 | They will not be included in the production build so you can use them for things like documentation.
155 |
156 | ## Available Scripts
157 |
158 | In the project directory, you can run:
159 |
160 | ### `npm start`
161 |
162 | Runs the app in the development mode.
163 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
164 |
165 | The page will reload if you make edits.
166 | You will also see any lint errors in the console.
167 |
168 | ### `npm test`
169 |
170 | Launches the test runner in the interactive watch mode.
171 | See the section about [running tests](#running-tests) for more information.
172 |
173 | ### `npm run build`
174 |
175 | Builds the app for production to the `build` folder.
176 | It correctly bundles React in production mode and optimizes the build for the best performance.
177 |
178 | The build is minified and the filenames include the hashes.
179 | Your app is ready to be deployed!
180 |
181 | See the section about [deployment](#deployment) for more information.
182 |
183 | ### `npm run eject`
184 |
185 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!**
186 |
187 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
188 |
189 | Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
190 |
191 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
192 |
193 | ## Supported Language Features and Polyfills
194 |
195 | This project supports a superset of the latest JavaScript standard.
196 | In addition to [ES6](https://github.com/lukehoban/es6features) syntax features, it also supports:
197 |
198 | * [Exponentiation Operator](https://github.com/rwaldron/exponentiation-operator) (ES2016).
199 | * [Async/await](https://github.com/tc39/ecmascript-asyncawait) (ES2017).
200 | * [Object Rest/Spread Properties](https://github.com/sebmarkbage/ecmascript-rest-spread) (stage 3 proposal).
201 | * [Dynamic import()](https://github.com/tc39/proposal-dynamic-import) (stage 3 proposal)
202 | * [Class Fields and Static Properties](https://github.com/tc39/proposal-class-public-fields) (part of stage 3 proposal).
203 | * [JSX](https://facebook.github.io/react/docs/introducing-jsx.html) and [Flow](https://flowtype.org/) syntax.
204 |
205 | Learn more about [different proposal stages](https://babeljs.io/docs/plugins/#presets-stage-x-experimental-presets-).
206 |
207 | While we recommend using experimental proposals with some caution, Facebook heavily uses these features in the product code, so we intend to provide [codemods](https://medium.com/@cpojer/effective-javascript-codemods-5a6686bb46fb) if any of these proposals change in the future.
208 |
209 | Note that **the project only includes a few ES6 [polyfills](https://en.wikipedia.org/wiki/Polyfill)**:
210 |
211 | * [`Object.assign()`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) via [`object-assign`](https://github.com/sindresorhus/object-assign).
212 | * [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) via [`promise`](https://github.com/then/promise).
213 | * [`fetch()`](https://developer.mozilla.org/en/docs/Web/API/Fetch_API) via [`whatwg-fetch`](https://github.com/github/fetch).
214 |
215 | If you use any other ES6+ features that need **runtime support** (such as `Array.from()` or `Symbol`), make sure you are including the appropriate polyfills manually, or that the browsers you are targeting already support them.
216 |
217 | ## Syntax Highlighting in the Editor
218 |
219 | To configure the syntax highlighting in your favorite text editor, head to the [relevant Babel documentation page](https://babeljs.io/docs/editors) and follow the instructions. Some of the most popular editors are covered.
220 |
221 | ## Displaying Lint Output in the Editor
222 |
223 | >Note: this feature is available with `react-scripts@0.2.0` and higher.
224 | >It also only works with npm 3 or higher.
225 |
226 | Some editors, including Sublime Text, Atom, and Visual Studio Code, provide plugins for ESLint.
227 |
228 | They are not required for linting. You should see the linter output right in your terminal as well as the browser console. However, if you prefer the lint results to appear right in your editor, there are some extra steps you can do.
229 |
230 | You would need to install an ESLint plugin for your editor first. Then, add a file called `.eslintrc` to the project root:
231 |
232 | ```js
233 | {
234 | "extends": "react-app"
235 | }
236 | ```
237 |
238 | Now your editor should report the linting warnings.
239 |
240 | Note that even if you edit your `.eslintrc` file further, these changes will **only affect the editor integration**. They won’t affect the terminal and in-browser lint output. This is because Create React App intentionally provides a minimal set of rules that find common mistakes.
241 |
242 | If you want to enforce a coding style for your project, consider using [Prettier](https://github.com/jlongster/prettier) instead of ESLint style rules.
243 |
244 | ## Debugging in the Editor
245 |
246 | **This feature is currently only supported by [Visual Studio Code](https://code.visualstudio.com) and [WebStorm](https://www.jetbrains.com/webstorm/).**
247 |
248 | Visual Studio Code and WebStorm support debugging out of the box with Create React App. This enables you as a developer to write and debug your React code without leaving the editor, and most importantly it enables you to have a continuous development workflow, where context switching is minimal, as you don’t have to switch between tools.
249 |
250 | ### Visual Studio Code
251 |
252 | You would need to have the latest version of [VS Code](https://code.visualstudio.com) and VS Code [Chrome Debugger Extension](https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome) installed.
253 |
254 | Then add the block below to your `launch.json` file and put it inside the `.vscode` folder in your app’s root directory.
255 |
256 | ```json
257 | {
258 | "version": "0.2.0",
259 | "configurations": [{
260 | "name": "Chrome",
261 | "type": "chrome",
262 | "request": "launch",
263 | "url": "http://localhost:3000",
264 | "webRoot": "${workspaceRoot}/src",
265 | "sourceMapPathOverrides": {
266 | "webpack:///src/*": "${webRoot}/*"
267 | }
268 | }]
269 | }
270 | ```
271 | >Note: the URL may be different if you've made adjustments via the [HOST or PORT environment variables](#advanced-configuration).
272 |
273 | Start your app by running `npm start`, and start debugging in VS Code by pressing `F5` or by clicking the green debug icon. You can now write code, set breakpoints, make changes to the code, and debug your newly modified code—all from your editor.
274 |
275 | Having problems with VS Code Debugging? Please see their [troubleshooting guide](https://github.com/Microsoft/vscode-chrome-debug/blob/master/README.md#troubleshooting).
276 |
277 | ### WebStorm
278 |
279 | You would need to have [WebStorm](https://www.jetbrains.com/webstorm/) and [JetBrains IDE Support](https://chrome.google.com/webstore/detail/jetbrains-ide-support/hmhgeddbohgjknpmjagkdomcpobmllji) Chrome extension installed.
280 |
281 | In the WebStorm menu `Run` select `Edit Configurations...`. Then click `+` and select `JavaScript Debug`. Paste `http://localhost:3000` into the URL field and save the configuration.
282 |
283 | >Note: the URL may be different if you've made adjustments via the [HOST or PORT environment variables](#advanced-configuration).
284 |
285 | Start your app by running `npm start`, then press `^D` on macOS or `F9` on Windows and Linux or click the green debug icon to start debugging in WebStorm.
286 |
287 | The same way you can debug your application in IntelliJ IDEA Ultimate, PhpStorm, PyCharm Pro, and RubyMine.
288 |
289 | ## Formatting Code Automatically
290 |
291 | Prettier is an opinionated code formatter with support for JavaScript, CSS and JSON. With Prettier you can format the code you write automatically to ensure a code style within your project. See the [Prettier's GitHub page](https://github.com/prettier/prettier) for more information, and look at this [page to see it in action](https://prettier.github.io/prettier/).
292 |
293 | To format our code whenever we make a commit in git, we need to install the following dependencies:
294 |
295 | ```sh
296 | npm install --save husky lint-staged prettier
297 | ```
298 |
299 | Alternatively you may use `yarn`:
300 |
301 | ```sh
302 | yarn add husky lint-staged prettier
303 | ```
304 |
305 | * `husky` makes it easy to use githooks as if they are npm scripts.
306 | * `lint-staged` allows us to run scripts on staged files in git. See this [blog post about lint-staged to learn more about it](https://medium.com/@okonetchnikov/make-linting-great-again-f3890e1ad6b8).
307 | * `prettier` is the JavaScript formatter we will run before commits.
308 |
309 | Now we can make sure every file is formatted correctly by adding a few lines to the `package.json` in the project root.
310 |
311 | Add the following line to `scripts` section:
312 |
313 | ```diff
314 | "scripts": {
315 | + "precommit": "lint-staged",
316 | "start": "react-scripts start",
317 | "build": "react-scripts build",
318 | ```
319 |
320 | Next we add a 'lint-staged' field to the `package.json`, for example:
321 |
322 | ```diff
323 | "dependencies": {
324 | // ...
325 | },
326 | + "lint-staged": {
327 | + "src/**/*.{js,jsx,json,css}": [
328 | + "prettier --single-quote --write",
329 | + "git add"
330 | + ]
331 | + },
332 | "scripts": {
333 | ```
334 |
335 | Now, whenever you make a commit, Prettier will format the changed files automatically. You can also run `./node_modules/.bin/prettier --single-quote --write "src/**/*.{js,jsx}"` to format your entire project for the first time.
336 |
337 | Next you might want to integrate Prettier in your favorite editor. Read the section on [Editor Integration](https://github.com/prettier/prettier#editor-integration) on the Prettier GitHub page.
338 |
339 | ## Changing the Page ``
340 |
341 | You can find the source HTML file in the `public` folder of the generated project. You may edit the `` tag in it to change the title from “React App” to anything else.
342 |
343 | Note that normally you wouldn’t edit files in the `public` folder very often. For example, [adding a stylesheet](#adding-a-stylesheet) is done without touching the HTML.
344 |
345 | If you need to dynamically update the page title based on the content, you can use the browser [`document.title`](https://developer.mozilla.org/en-US/docs/Web/API/Document/title) API. For more complex scenarios when you want to change the title from React components, you can use [React Helmet](https://github.com/nfl/react-helmet), a third party library.
346 |
347 | If you use a custom server for your app in production and want to modify the title before it gets sent to the browser, you can follow advice in [this section](#generating-dynamic-meta-tags-on-the-server). Alternatively, you can pre-build each page as a static HTML file which then loads the JavaScript bundle, which is covered [here](#pre-rendering-into-static-html-files).
348 |
349 | ## Installing a Dependency
350 |
351 | The generated project includes React and ReactDOM as dependencies. It also includes a set of scripts used by Create React App as a development dependency. You may install other dependencies (for example, React Router) with `npm`:
352 |
353 | ```sh
354 | npm install --save react-router
355 | ```
356 |
357 | Alternatively you may use `yarn`:
358 |
359 | ```sh
360 | yarn add react-router
361 | ```
362 |
363 | This works for any library, not just `react-router`.
364 |
365 | ## Importing a Component
366 |
367 | This project setup supports ES6 modules thanks to Babel.
368 | While you can still use `require()` and `module.exports`, we encourage you to use [`import` and `export`](http://exploringjs.com/es6/ch_modules.html) instead.
369 |
370 | For example:
371 |
372 | ### `Button.js`
373 |
374 | ```js
375 | import React, { Component } from 'react';
376 |
377 | class Button extends Component {
378 | render() {
379 | // ...
380 | }
381 | }
382 |
383 | export default Button; // Don’t forget to use export default!
384 | ```
385 |
386 | ### `DangerButton.js`
387 |
388 |
389 | ```js
390 | import React, { Component } from 'react';
391 | import Button from './Button'; // Import a component from another file
392 |
393 | class DangerButton extends Component {
394 | render() {
395 | return ;
396 | }
397 | }
398 |
399 | export default DangerButton;
400 | ```
401 |
402 | Be aware of the [difference between default and named exports](http://stackoverflow.com/questions/36795819/react-native-es-6-when-should-i-use-curly-braces-for-import/36796281#36796281). It is a common source of mistakes.
403 |
404 | We suggest that you stick to using default imports and exports when a module only exports a single thing (for example, a component). That’s what you get when you use `export default Button` and `import Button from './Button'`.
405 |
406 | Named exports are useful for utility modules that export several functions. A module may have at most one default export and as many named exports as you like.
407 |
408 | Learn more about ES6 modules:
409 |
410 | * [When to use the curly braces?](http://stackoverflow.com/questions/36795819/react-native-es-6-when-should-i-use-curly-braces-for-import/36796281#36796281)
411 | * [Exploring ES6: Modules](http://exploringjs.com/es6/ch_modules.html)
412 | * [Understanding ES6: Modules](https://leanpub.com/understandinges6/read#leanpub-auto-encapsulating-code-with-modules)
413 |
414 | ## Code Splitting
415 |
416 | Instead of downloading the entire app before users can use it, code splitting allows you to split your code into small chunks which you can then load on demand.
417 |
418 | This project setup supports code splitting via [dynamic `import()`](http://2ality.com/2017/01/import-operator.html#loading-code-on-demand). Its [proposal](https://github.com/tc39/proposal-dynamic-import) is in stage 3. The `import()` function-like form takes the module name as an argument and returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) which always resolves to the namespace object of the module.
419 |
420 | Here is an example:
421 |
422 | ### `moduleA.js`
423 |
424 | ```js
425 | const moduleA = 'Hello';
426 |
427 | export { moduleA };
428 | ```
429 | ### `App.js`
430 |
431 | ```js
432 | import React, { Component } from 'react';
433 |
434 | class App extends Component {
435 | handleClick = () => {
436 | import('./moduleA')
437 | .then(({ moduleA }) => {
438 | // Use moduleA
439 | })
440 | .catch(err => {
441 | // Handle failure
442 | });
443 | };
444 |
445 | render() {
446 | return (
447 |
448 |
449 |
450 | );
451 | }
452 | }
453 |
454 | export default App;
455 | ```
456 |
457 | This will make `moduleA.js` and all its unique dependencies as a separate chunk that only loads after the user clicks the 'Load' button.
458 |
459 | You can also use it with `async` / `await` syntax if you prefer it.
460 |
461 | ### With React Router
462 |
463 | If you are using React Router check out [this tutorial](http://serverless-stack.com/chapters/code-splitting-in-create-react-app.html) on how to use code splitting with it. You can find the companion GitHub repository [here](https://github.com/AnomalyInnovations/serverless-stack-demo-client/tree/code-splitting-in-create-react-app).
464 |
465 | ## Adding a Stylesheet
466 |
467 | This project setup uses [Webpack](https://webpack.js.org/) for handling all assets. Webpack offers a custom way of “extending” the concept of `import` beyond JavaScript. To express that a JavaScript file depends on a CSS file, you need to **import the CSS from the JavaScript file**:
468 |
469 | ### `Button.css`
470 |
471 | ```css
472 | .Button {
473 | padding: 20px;
474 | }
475 | ```
476 |
477 | ### `Button.js`
478 |
479 | ```js
480 | import React, { Component } from 'react';
481 | import './Button.css'; // Tell Webpack that Button.js uses these styles
482 |
483 | class Button extends Component {
484 | render() {
485 | // You can use them as regular CSS styles
486 | return ;
487 | }
488 | }
489 | ```
490 |
491 | **This is not required for React** but many people find this feature convenient. You can read about the benefits of this approach [here](https://medium.com/seek-ui-engineering/block-element-modifying-your-javascript-components-d7f99fcab52b). However you should be aware that this makes your code less portable to other build tools and environments than Webpack.
492 |
493 | In development, expressing dependencies this way allows your styles to be reloaded on the fly as you edit them. In production, all CSS files will be concatenated into a single minified `.css` file in the build output.
494 |
495 | If you are concerned about using Webpack-specific semantics, you can put all your CSS right into `src/index.css`. It would still be imported from `src/index.js`, but you could always remove that import if you later migrate to a different build tool.
496 |
497 | ## Post-Processing CSS
498 |
499 | This project setup minifies your CSS and adds vendor prefixes to it automatically through [Autoprefixer](https://github.com/postcss/autoprefixer) so you don’t need to worry about it.
500 |
501 | For example, this:
502 |
503 | ```css
504 | .App {
505 | display: flex;
506 | flex-direction: row;
507 | align-items: center;
508 | }
509 | ```
510 |
511 | becomes this:
512 |
513 | ```css
514 | .App {
515 | display: -webkit-box;
516 | display: -ms-flexbox;
517 | display: flex;
518 | -webkit-box-orient: horizontal;
519 | -webkit-box-direction: normal;
520 | -ms-flex-direction: row;
521 | flex-direction: row;
522 | -webkit-box-align: center;
523 | -ms-flex-align: center;
524 | align-items: center;
525 | }
526 | ```
527 |
528 | If you need to disable autoprefixing for some reason, [follow this section](https://github.com/postcss/autoprefixer#disabling).
529 |
530 | ## Adding a CSS Preprocessor (Sass, Less etc.)
531 |
532 | Generally, we recommend that you don’t reuse the same CSS classes across different components. For example, instead of using a `.Button` CSS class in `` and `` components, we recommend creating a `