├── .gitignore ├── README.md ├── babel.config.js ├── docs ├── .gitignore ├── package.json ├── src │ ├── .vuepress │ │ ├── config.js │ │ ├── enhanceApp.js │ │ ├── public │ │ │ └── frontend-masters-logo.png │ │ └── styles │ │ │ ├── index.styl │ │ │ └── palette.styl │ ├── guide │ │ ├── components.md │ │ ├── core-principles.md │ │ ├── easy-to-follow-best-practices.md │ │ ├── final-thoughts.md │ │ ├── index.md │ │ ├── languages.md │ │ ├── reusability-and-composition.md │ │ ├── routing.md │ │ ├── state-management.md │ │ ├── testing.md │ │ └── vue-cli.md │ └── index.md └── yarn.lock ├── package.json ├── public ├── favicon.ico └── index.html ├── resources └── Production-Grade-Vue.pdf ├── src ├── App.vue ├── assets │ └── logo.png ├── components │ ├── CompositionCounter.vue │ ├── DynamicHeading.vue │ ├── HelloWorld.vue │ └── ManagingTernaryStyles.vue └── main.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # Editor directories and files 17 | .idea 18 | .vscode 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw? 24 | 25 | # Local Netlify folder 26 | .netlify -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Production-Grade Vue 2 | 3 | The official repo for [Frontend Masters Workshop: Production-Grade Vue](https://frontendmasters.com/courses/production-vue/)! 4 | 5 | ## Resources 6 | 7 | - [Slides](https://github.com/bencodezen/production-grade-vue/blob/01-challenge-solution/resources/Production-Grade-Vue.pdf) 8 | - [Official Docs](https://production-grade-vue.bencodezen.io/) 9 | 10 | ## Challenges 11 | 12 | - 01: Render Function + CSS Modules 13 | - [Challenge Description](https://production-grade-vue.bencodezen.io/guide/languages.html#challenge-01) 14 | - [Solution Branch](https://github.com/bencodezen/production-grade-vue/tree/01-challenge-solution) 15 | - 02: Composition API Counter 16 | - [Challenge Description](https://production-grade-vue.bencodezen.io/guide/reusability-and-composition.html#challenge-02) 17 | - [Solution Branch](https://github.com/bencodezen/production-grade-vue/tree/02-challenge-counter-solution) 18 | 19 | ## Setting Up Local Environment 20 | 21 | ```bash 22 | # Install dependencies 23 | yarn install 24 | 25 | # Start local dev server 26 | yarn serve 27 | ``` 28 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | pids 2 | logs 3 | node_modules 4 | npm-debug.log 5 | coverage/ 6 | run 7 | dist 8 | .DS_Store 9 | .nyc_output 10 | .basement 11 | config.local.js 12 | basement_dist 13 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "production-grade-vue-docs", 3 | "version": "0.0.1", 4 | "description": "Documentation for Production-Grade Vue with Frontend Masters", 5 | "main": "index.js", 6 | "authors": { 7 | "name": "Ben Hong", 8 | "email": "ben@bencodezen.io" 9 | }, 10 | "repository": "https://github.com/bencodezen/production-grade-vue/production-grade-vue-docs", 11 | "scripts": { 12 | "dev": "vuepress dev src", 13 | "build": "vuepress build src" 14 | }, 15 | "license": "MIT", 16 | "devDependencies": { 17 | "vuepress": "^1.7.1" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /docs/src/.vuepress/config.js: -------------------------------------------------------------------------------- 1 | const { description } = require('../../package'); 2 | 3 | module.exports = { 4 | /** 5 | * Ref:https://v1.vuepress.vuejs.org/config/#title 6 | */ 7 | title: 'Production-Grade Vue', 8 | /** 9 | * Ref:https://v1.vuepress.vuejs.org/config/#description 10 | */ 11 | description: 12 | 'Building applications that can scale and grow is more than simply following a series of rules. In this workshop, you will learn proven patterns for building production Vue.js apps while gaining an understanding of why certain patterns exist. Equipped with this, you will feel more confident in choosing what is best for your application.', 13 | 14 | /** 15 | * Extra tags to be injected to the page HTML `` 16 | * 17 | * ref:https://v1.vuepress.vuejs.org/config/#head 18 | */ 19 | head: [ 20 | ['meta', { name: 'theme-color', content: '#3eaf7c' }], 21 | ['meta', { name: 'apple-mobile-web-app-capable', content: 'yes' }], 22 | [ 23 | 'meta', 24 | { name: 'apple-mobile-web-app-status-bar-style', content: 'black' } 25 | ] 26 | ], 27 | 28 | /** 29 | * Theme configuration, here is the default theme configuration for VuePress. 30 | * 31 | * ref:https://v1.vuepress.vuejs.org/theme/default-theme-config.html 32 | */ 33 | themeConfig: { 34 | repo: 'https://github.com/bencodezen/production-grade-vue', 35 | editLinks: false, 36 | docsDir: 'docs', 37 | editLinkText: 'Edit this page', 38 | lastUpdated: true, 39 | nav: [ 40 | { 41 | text: 'Guide', 42 | link: '/guide/' 43 | }, 44 | { 45 | text: 'Config', 46 | link: '/config/' 47 | }, 48 | { 49 | text: 'VuePress', 50 | link: 'https://v1.vuepress.vuejs.org' 51 | } 52 | ], 53 | sidebar: [ 54 | '/guide/', 55 | '/guide/languages', 56 | '/guide/vue-cli', 57 | '/guide/components', 58 | '/guide/reusability-and-composition', 59 | '/guide/state-management', 60 | '/guide/routing', 61 | '/guide/testing', 62 | '/guide/easy-to-follow-best-practices', 63 | '/guide/core-principles', 64 | '/guide/final-thoughts' 65 | ] 66 | }, 67 | 68 | /** 69 | * Apply plugins,ref:https://v1.vuepress.vuejs.org/zh/plugin/ 70 | */ 71 | plugins: ['@vuepress/plugin-back-to-top', '@vuepress/plugin-medium-zoom'] 72 | }; 73 | -------------------------------------------------------------------------------- /docs/src/.vuepress/enhanceApp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Client app enhancement file. 3 | * 4 | * https://v1.vuepress.vuejs.org/guide/basic-config.html#app-level-enhancements 5 | */ 6 | 7 | export default ({ 8 | Vue, // the version of Vue being used in the VuePress app 9 | options, // the options for the root Vue instance 10 | router, // the router instance for the app 11 | siteData // site metadata 12 | }) => { 13 | // ...apply enhancements for the site. 14 | } 15 | -------------------------------------------------------------------------------- /docs/src/.vuepress/public/frontend-masters-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bencodezen/production-grade-vue/7b298c41dbc8f0266482b50fb66721fed7fff4aa/docs/src/.vuepress/public/frontend-masters-logo.png -------------------------------------------------------------------------------- /docs/src/.vuepress/styles/index.styl: -------------------------------------------------------------------------------- 1 | /** 2 | * Custom Styles here. 3 | * 4 | * ref:https://v1.vuepress.vuejs.org/config/#index-styl 5 | */ 6 | 7 | .home .hero img 8 | max-width 450px!important 9 | -------------------------------------------------------------------------------- /docs/src/.vuepress/styles/palette.styl: -------------------------------------------------------------------------------- 1 | /** 2 | * Custom palette here. 3 | * 4 | * ref:https://v1.vuepress.vuejs.org/zh/config/#palette-styl 5 | */ 6 | 7 | $accentColor = #3eaf7c 8 | $textColor = #2c3e50 9 | $borderColor = #eaecef 10 | $codeBgColor = #282c34 11 | -------------------------------------------------------------------------------- /docs/src/guide/components.md: -------------------------------------------------------------------------------- 1 | # Components 2 | 3 | ## Part 1 4 | 5 | ### Naming Components 6 | 7 | - Avoid single word components 8 | - Prefix components with words like `App` or `Base` or a unique company/team identifier 9 | - For component where only a single instance should exist, prefix with `The` 10 | - Tightly related components should be also named as such to maintain an obvious relationship between them: `TodoList > TodoListItem > TodoListItemName` 11 | 12 | ### Naming Component Methods 13 | 14 | - Use descriptive names (e.g., `updateUserName`) 15 | - Do not name it after the event (e.g., `onInput`) 16 | - When you name it after the event, this assumes where it will be called and will make refactoring difficult later on 17 | - Prefer destructuring over multiple argument. In other words, allow users to "configure" their options by letting them assign values to an object rather than memorizing what order the parameters are in 18 | 19 | ```js 20 | // * Recommended 21 | updateUser ({ userList, index, value, isOnline }) { 22 | if (isOnline) { 23 | userList[index] = value 24 | } else { 25 | this.removeUser(userList, index) 26 | } 27 | } 28 | 29 | // ! Not recommended 30 | updateUser (userList, index, value, isOnline) { 31 | if (isOnline) { 32 | userList[index] = value 33 | } else { 34 | this.removeUser(userList, index) 35 | } 36 | } 37 | ``` 38 | 39 | ### When to Refactor Components 40 | 41 | - Data Driven Refactoring 42 | - Signs you need more components 43 | - When your components are hard to understand 44 | - You feel a fragment of a component could use its own state 45 | - Hard to describe what what the component is actually responsible for 46 | - How to find reusable components 47 | - Look for v-for loops 48 | - Look for large components 49 | - Look for similar visual designs 50 | - Look for repeating interface fragments 51 | - Look for multiple/mixed responsibilities 52 | - Look for complicated data paths 53 | 54 | ### SFC Block Order 55 | 56 | Recommend using `script > template > style` in order to optimize for scrolling experience for better shared concerns amongst the file. 57 | 58 | ```vue 59 | 64 | 65 | 68 | 69 | 72 | ``` 73 | 74 | ### Component File Organization 75 | 76 | - Recommend flatter file organization over heavily nested files 77 | - Flat make refactoring easier since imports don't have update their paths 78 | - Flat makes finding files easier as well since deeply nested files don't have to be unique and can be lazily named 79 | 80 | ### Register base components globally 81 | 82 | - Base components are used so often the savings of importing them manually often do not outweigh the cost of developers manually importing them 83 | - Check out this great script by Chris Fritz: https://vuejs.org/v2/guide/components-registration.html#Automatic-Global-Registration-of-Base-Components 84 | 85 | ## Part 2 86 | 87 | ### Props 88 | 89 | - Avoid using arrays to define components 90 | - Use object to define whether a prop is required or has a default value 91 | - You do not need both required and default on a prop definition 92 | - You can also add custom validators to add more specific type constraints 93 | 94 | ### Let's do a coding experiment 95 | 96 | - Experiment building a button that has growing requirements 97 | - Prop solutions are great for being very descriptive for how something should be used, but it does have some issues: 98 | - New requirements increase complexity 99 | - Multiple responsibilities 100 | - Lots of conditionals in the template 101 | - Low flexibility 102 | - Hard to maintain 103 | 104 | ### How to dynamically switch components based on data 105 | 106 | - Use the `` component 107 | - Benefits of using it include: 108 | - Extremely powerful and flexible 109 | - Easy to use 110 | - Can accept props 111 | - Can accept asynchronous components 112 | - Can change into different components 113 | - You can make a router-view out of it 114 | - But when you use it, be careful of how you handle props 115 | 116 | ### Vendor component wrapper 117 | 118 | - Wrap all components using third party libraries in your own component to allow for easier refactoring and management 119 | 120 | ```vue 121 | 125 | ``` 126 | 127 | ### Transparent components 128 | 129 | - When creating your own components around native HTML elements, make sure you assign the correct attrs to the right elements 130 | - By default, it goes to the root element, but you need disable `inheritAttrs` so you can reassign where everything goes 131 | -------------------------------------------------------------------------------- /docs/src/guide/core-principles.md: -------------------------------------------------------------------------------- 1 | ## Core Principles 2 | 3 | - Impact over intent 4 | - Context is everything 5 | - All code is compromise 6 | -------------------------------------------------------------------------------- /docs/src/guide/easy-to-follow-best-practices.md: -------------------------------------------------------------------------------- 1 | ## Best Practices 2 | 3 | - Why best practices are important? 4 | - What do we all want at the end of the day? 5 | - Faster development 6 | - Fewer bugs 7 | - More opportunities for learning 8 | - Instead of best practices, think of them as chosen conventions - instead. 9 | - What makes a convention "good"? 10 | - There are two main factors that contribute to whether a convention is good or not: 11 | - They enable developers to write great code with a low barrier of entry 12 | - They are easy to refactor and/or abandon 13 | - How to implement conventions 14 | - There are three main stages to implementing chosen conventions: 15 | - Selection 16 | - Define the problem 17 | - Things are rarely objective and absolute 18 | - Avoid bike-shedding 19 | - Time-constrained voting 20 | - Disagree and commit 21 | - 3 month discussion freezes 22 | - Implementation 23 | - Automate everything 24 | - Linters (i.e., eslint, stylelint, markdownlint) 25 | - Formatters (i.e., prettier) 26 | - Image Optimization (i.e., image-min) 27 | - Generators (i.e., hygen/plop) 28 | - Code Snippets (i..e, VS Code) 29 | - Maintenance 30 | - Build emotional safety and awareness 31 | - Don't blame individuals 32 | - Find systematic solutions 33 | - If you have power, protect your devs 34 | - The Jidoka principle 35 | - Discover an abnormality 36 | - Stop the process 37 | - Fix the immediate process 38 | - Investigate and solve the root cause 39 | - The Andon Cord 40 | -------------------------------------------------------------------------------- /docs/src/guide/final-thoughts.md: -------------------------------------------------------------------------------- 1 | ## Final Thoughts 2 | 3 | - Resources 4 | - Congratulations 5 | - Farewell 6 | -------------------------------------------------------------------------------- /docs/src/guide/index.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Welcome to "Production-Grade Vue" hosted by Frontend Masters! 4 | 5 | ## What is this course about? 6 | 7 | Building applications that can scale and grow is more than simply following a series of rules. In this workshop, you will learn proven patterns for building production Vue.js apps while gaining an understanding of why certain patterns exist. Equipped with this, you will feel more confident in choosing what is best for your application. 8 | 9 | This course is unique to typical intermediate to advanced Vue.js courses because this course is not merely a list of tools and techniques to memorize, but it is designed to familiarize you with key concepts and ideas that go into creating production level Vue.js applications. As we know with most technology, techniques come and go and are useful in certain contexts while harmful in others, that is why the ideas taught in this course are key to building production Vue.js applications. 10 | 11 | ## Who am I? 12 | 13 | My name is Ben Hong and I'm a Vue.js Core Team member and Senior DX Engineer at Netlify. 14 | 15 | If you'd like to connect with me on social media, you can find me at: 16 | 17 | - [Twitter](https://www.twitter.com/bencodezen) 18 | - [YouTube](https://www.youtube.com/bencodezen) 19 | - [GitHub](https://www.github.com/bencodezen) 20 | - [Instagram](https://www.instagram.com/bencodezen) 21 | 22 | ## Why did I create this course? 23 | 24 | The reason I created this course because while there are a lot of different ways to solve the same problem in Vue.js, there a lot of best practices, patterns and ideas that a lot of people would benefit from knowing so that they can create the best apps possible they can. 25 | 26 | And of course, a big thank you goes out to Frontend Masters for making this course a reality. 27 | 28 | Frontend Masters Logo 29 | 30 | ## Where do I file issues? 31 | 32 | My goal with every course I create is to avoid making mistakes. That said, there will be times where there will be errors. And in the event you find any mistakes in the material, please be sure to [file a new issue](https://github.com/bencodezen/production-grade-vue/issues) or [pull request](https://github.com/bencodezen/production-grade-vue/pulls) on the GitHub repo. 33 | -------------------------------------------------------------------------------- /docs/src/guide/languages.md: -------------------------------------------------------------------------------- 1 | # Languages 2 | 3 | ## Single File Components (Overview) 4 | 5 | Most components written in Vue.js are written as single-file components. 6 | 7 | ```vue 8 | 11 | 12 | 17 | 18 | 21 | ``` 22 | 23 | ## JavaScript 24 | 25 | - Majority of bugs encountered are not due to type violations 26 | - TypeScript does not inherently guarantee type safety - it requires discipline 27 | - Full type safety in a codebase can be a significant cost to a team in terms of productivity 28 | - There is also the cost of onboarding that needs to be considered since more and more developers are started with languages that are not strongly-typed and the learning curve can be an added cost for teams 29 | - Most applications would benefit from better tests and code reviews 30 | - Progressive types can be added to a codebase with JSDoc comments 31 | - Resource: [Type Vue without TypeScript](https://blog.usejournal.com/type-vue-without-typescript-b2b49210f0b) by [Rahul Kadyan](https://twitter.com/znck0) 32 | - If the application is in Vue.js 2, probably not worth upgrading to TypeScript 33 | - Starting a new project with Vue.js 3 and the team is interested in trying it out TypeScript? Go for it! 34 | 35 | ## HTML 36 | 37 | ### All HTML should exist in .vue files in a template or render function 38 | 39 | A benefit of doing this is that Vue has an opportunity to parse it before the browser does. 40 | 41 | This allows for developer experience improvements such as: 42 | 43 | - Self-closing tags 44 | - Easy enhancement path if needed 45 | 46 | ### Template (Overview) 47 | 48 | ```vue{1-3} 49 | 52 | 53 | 58 | 59 | 62 | ``` 63 | 64 | ### Render Function (Overview) 65 | 66 | This is another valid alternative for generating HTML when you need to do it programmatically, but generally `template` is recommended over `render` functions. 67 | 68 | #### Vue 2 69 | 70 | ```vue 71 | 78 | ``` 79 | 80 | #### Vue 3 81 | 82 | ```vue 83 | 92 | ``` 93 | 94 | ### Template vs Render Function 95 | 96 | Templates are the most declarative way to write HTML and is recommended as the default. 97 | 98 | Render functions are a valid alternative to templates that are great for programmatic generation of markup. 99 | 100 | ### v-bind and v-on Object Syntax 101 | 102 | The following code: 103 | 104 | ```vue 105 | 113 | ``` 114 | 115 | can be rewritten as: 116 | 117 | ```vue 118 | 119 | ``` 120 | 121 | ## CSS 122 | 123 | In general, limit global styles to App.vue whenever possible. 124 | 125 | Otherwise, tyr to scope all component styles with scoped styles or CSS modules. 126 | 127 | ### Scoped Styles 128 | 129 | Utilizes a data attribute in order to "scope" the styles to the HTML generated, but it's limited in protecting the element since higher specificity can still override this. 130 | 131 | ```vue 132 | 136 | 137 | 145 | ``` 146 | 147 | ### CSS Modules 148 | 149 | What I recommend in terms of managing styles inside of components. It generates a unique CSS class that avoid the specificity issue. 150 | 151 | ```vue 152 | 155 | 156 | 164 | ``` 165 | 166 | ## Challenge 01 167 | 168 | ### In the repo 169 | 170 | - Rewrite the `DynamicHeading` component using the render function 171 | - Refactor the `#app` styles to a CSS class and use CSS modules 172 | 173 | ### In your app 174 | 175 | - Look around to see if there are any components that might benefit from using the render method instead of templates 176 | - Refactor a component to use CSS modules 177 | -------------------------------------------------------------------------------- /docs/src/guide/reusability-and-composition.md: -------------------------------------------------------------------------------- 1 | # Reusability and Composition 2 | 3 | ## Mixins 4 | 5 | - Pros 6 | - Relatively easy to use 7 | - Good for refactoring 8 | - Cons 9 | - Possible properties name clashes. 10 | - Can’t share template fragments 11 | - Gets harder to track where things are coming from once there are more mixins 12 | 13 | ## Provide / Inject 14 | 15 | - Pros 16 | - Easy sharing data and methods with descendants 17 | - Helps avoiding unnecessary props 18 | - Components can choose which properties to inject 19 | - Can be used to provide default props and data values 20 | - Cons 21 | - There are some reactivity caveats when it comes to usage in Vue 2 22 | - Creates a tight relationship between two components that is not immediately apparent 23 | - There is ambiguity when it comes to what is coming from where 24 | 25 | ## Composition API 26 | 27 | - Resource: [Official Vue.js 3 Composition API Guide](https://v3.vuejs.org/guide/composition-api-introduction.html) 28 | 29 | ## Challenge 02 30 | 31 | - Create a counter that uses the Composition API to: 32 | - Keep track of a currentCount 33 | - Increment the count 34 | - Change the amount that the count can be incremented by 35 | -------------------------------------------------------------------------------- /docs/src/guide/routing.md: -------------------------------------------------------------------------------- 1 | ## Routing 2 | 3 | - Three main categories of routing 4 | - View Components - Definition for page level components (i.e., Home, About, Dashboard) 5 | - Layout Components - Markup shared between pages (i.e., header, sidebar, etc.) 6 | - Routes - Define how paths map to view components 7 | - Add dynamic key to route-view components 8 | - vue-meta 9 | - Lazy load routes 10 | -------------------------------------------------------------------------------- /docs/src/guide/state-management.md: -------------------------------------------------------------------------------- 1 | # State Management 2 | 3 | - 📢 Need an introduction to Vuex? Check out Sarah's course: Intro to Vue 3! 4 | - 📢 Need a deeper dive Vuex? Check out Divya's course: Vuex for Intermediate Vue.js Developers! 5 | 6 | ## What data to put into Vuex? 7 | 8 | - Data shared between components that might not be in direct parent-child relation 9 | - Data that you want to keep between router views (for example lists of records fetched from the API) 10 | - Route params are more important though (as a source of truth) 11 | - Any kind of global state 12 | - Examples: login status, user information, global notifications 13 | - Anything if you feel it will make managing it simpler 14 | 15 | ## What data to avoid putting into Vuex? 16 | 17 | - User Interface variables 18 | - Examples: isDropdownOpen, isInputFocused, isModalVisible 19 | - Forms data 20 | - Validation results 21 | - Single records from the API 22 | 23 | ## Other advice 24 | 25 | - Avoid calling mutations directly in components 26 | - Use built-in map helpers 27 | - mapActions vs mapMutations 28 |  - 📢 Need an intro to mapHelpers to Vuex? Check out Divya's course: Vuex for Intermediate Vue.js Developers! 29 |  - Don't use mapMutations 30 |  - Different ways to define mapActions 31 | - Always use namespaced module 32 |  - 📢 Need an intro to modules to Vuex? Check out Divya's course: Vuex for Intermediate Vue.js Developers! 33 |  - Mutations and actions are not namespsaced by default, this is why it's important to turn this on by default. 34 | - Composition API's Impact on Vuex 35 | -------------------------------------------------------------------------------- /docs/src/guide/testing.md: -------------------------------------------------------------------------------- 1 | ## Testing 2 | 3 | - The Pareto Principle 4 | - Best practice of writing unit tests 5 | - Don't test that Vue works 6 | - Examples: Checking that a data, computed, etc property exists 7 | - Primarily stick with shallow rendering 8 | - Otherwise a problem in a common component can break many tests 9 | - Build unit tests into generators 10 | - Traditional Testing Model 11 | - Unit tests are great, but they're often not the 20% we should be focusing on 12 | - The Two Tests to Focus On 13 | - Can the user login? 14 | - Can the user pay us? 15 | - Best practice for writing e2e tests 16 | - Don't maintain state between tests 17 | - Tests should be able to run independently of one another 18 | - Don't select elements with classes 19 | - Think from the user's perspective, or select elements by their intent 20 | -------------------------------------------------------------------------------- /docs/src/guide/vue-cli.md: -------------------------------------------------------------------------------- 1 | ## Vue CLI 2 | 3 | ### Vue CLI 4 | 5 | - Setup a Vue 3 project on the repo 6 | 7 | ### Vue UI GUI 8 | 9 | - Once Vue CLI is installed locally, you can run this with `vue ui` 10 | - Equivalent of Vue CLI with DX magic 11 |  - Need to kill a port because something was left running? 12 |  - Check out how easy it is to configure things 13 |  - When you run your server, you also get statistics and analysis 14 | 15 | ### Vue CLI - Modern Mode 16 | 17 | - Babel allows us to utilize all the newest language features in ES6+, but this also means that traditional bundling strategies meant you had to include all of this to users who didn't need it 18 |  - With modern mode, Vue CLI products two versions of your app: one modern bundle targeting browsers that support ES modules, and a legacy bundle targeting older browsers that do not. 19 |  - The best thing about this is that beyond ensuring your build process has this flag checked off, you don't need to do anything else. 20 | - The command is `vue-cli-service build --modern` 21 | 22 | ### Valid alternatives to Vue CLI 23 | 24 | - Micro-frontends 25 | - Legacy migration 26 | - Server-side rendering 27 | -------------------------------------------------------------------------------- /docs/src/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | home: true 3 | heroImage: https://v1.vuepress.vuejs.org/hero.png 4 | tagline: Official guide for Production-Grade Vue with Frontend Masters 5 | actionText: Read the Guide → 6 | actionLink: /guide/ 7 | footer: Made by Ben Hong with ❤️ 8 | --- 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "production-grade-vue", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "core-js": "^3.6.5", 12 | "vue": "^3.0.0" 13 | }, 14 | "devDependencies": { 15 | "@vue/cli-plugin-babel": "~4.5.0", 16 | "@vue/cli-plugin-eslint": "~4.5.0", 17 | "@vue/cli-service": "~4.5.0", 18 | "@vue/compiler-sfc": "^3.0.0", 19 | "babel-eslint": "^10.1.0", 20 | "eslint": "^6.7.2", 21 | "eslint-plugin-vue": "^7.0.0-0" 22 | }, 23 | "eslintConfig": { 24 | "root": true, 25 | "env": { 26 | "node": true 27 | }, 28 | "extends": [ 29 | "plugin:vue/vue3-essential", 30 | "eslint:recommended" 31 | ], 32 | "parserOptions": { 33 | "parser": "babel-eslint" 34 | }, 35 | "rules": {} 36 | }, 37 | "browserslist": [ 38 | "> 1%", 39 | "last 2 versions", 40 | "not dead" 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bencodezen/production-grade-vue/7b298c41dbc8f0266482b50fb66721fed7fff4aa/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= htmlWebpackPlugin.options.title %> 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /resources/Production-Grade-Vue.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bencodezen/production-grade-vue/7b298c41dbc8f0266482b50fb66721fed7fff4aa/resources/Production-Grade-Vue.pdf -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 19 | 20 | 31 | -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bencodezen/production-grade-vue/7b298c41dbc8f0266482b50fb66721fed7fff4aa/src/assets/logo.png -------------------------------------------------------------------------------- /src/components/CompositionCounter.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 31 | 32 | 38 | -------------------------------------------------------------------------------- /src/components/DynamicHeading.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 41 | 42 | 43 | 59 | -------------------------------------------------------------------------------- /src/components/ManagingTernaryStyles.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 27 | 28 | 37 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import App from './App.vue' 3 | 4 | createApp(App).mount('#app') 5 | --------------------------------------------------------------------------------