Repository: phoenixframework/phoenix
Pull request #4260 (2021-03-16 18:13:04)

Update directory_structure.md
Hi Phoenix team, here are some updates to your documentation for your review.

Changes:

* Added some full-stops where needed for consistency.
* Added some notes about the `assets` directory

The goal I had in mind was to let devs know where they should start making changes to their front-end application (and not, for example, start making changes directly in the `priv/static` folder).

cw789: What if Phoenix is used without Webpack (`--no-webpack`)?
joeapearson: > What if Phoenix is used without Webpack (--no-webpack)?

I did think about that and you're right that's why I intentionally added the word "default".  It's easy to miss though... I just added some clarification.

Patch:
diff --git a/guides/deployment/releases.md b/guides/deployment/releases.md
index d61805d58..dd43f0bd3 100644
--- a/guides/deployment/releases.md
+++ b/guides/deployment/releases.md
@@ -245,3 +245,4 @@ A few points about configuring a containerized application:
 
 - If you run your app in a container, the `Endpoint` needs to be configured to listen on a "public" `:ip` address (like `0.0.0.0.0.0.0.0`) so that the app can be reached from outside the container. Whether the host should publish the container's ports to its own public IP or to localhost depends on your needs.
 - The more configuration you can provide at runtime (using `config/runtime.exs`), the more reusable your images will be across environments. In particular, secrets like database credentials and API keys should not be compiled into the image, but rather should be provided when creating containers based on that image. This is why the `Endpoint`'s `:secret_key_base` is configured in `config/runtime.exs` by default.
+- If possible, any environment variables that are needed at runtime should be read in `config/runtime.exs`, not scattered throughout your code. Having them all visible in one place will make it easier to ensure the containers get what they need, especially if the person doing the infrastructure work does not work on the Elixir code. Libraries in particular should never directly read environment variables; all their configuration should be handed to them by the top-level application, preferably [without using the application environment](https://hexdocs.pm/elixir/library-guidelines.html#avoid-application-configuration).
diff --git a/guides/directory_structure.md b/guides/directory_structure.md
index d678f78bc..7ae4ede90 100644
--- a/guides/directory_structure.md
+++ b/guides/directory_structure.md
@@ -20,19 +20,19 @@ When we use `mix phx.new` to generate a new Phoenix application, it builds a top
 
 We will go over those directories one by one:
 
-  * `_build` - a directory created by the `mix` command line tool that ships as part of Elixir that holds all compilation artifacts. As we have seen in "[Up and Running](up_and_running.html)", `mix` is the main interface to your application. We use Mix to compile our code, create databases, run our server, and more. This directory must not be checked into version control and it can be removed at any time. Removing it will force Mix to rebuild your application from scratch
+  * `_build` - a directory created by the `mix` command line tool that ships as part of Elixir that holds all compilation artifacts. As we have seen in "[Up and Running](up_and_running.html)", `mix` is the main interface to your application. We use Mix to compile our code, create databases, run our server, and more. This directory must not be checked into version control and it can be removed at any time. Removing it will force Mix to rebuild your application from scratch.
 
-  * `assets` - a directory that keeps everything related to front-end assets, such as JavaScript, CSS, static images and more. It is typically handled by the `npm` tool. Phoenix developers typically only need to run `npm install` inside the assets directory. Everything else is managed by Phoenix
+  * `assets` - a directory that keeps everything related to front-end assets, such as JavaScript, CSS, static images and more. It is typically handled by the `npm` tool. Phoenix developers typically only need to run `npm install` inside the assets directory. Everything else is managed by Phoenix.
 
-  * `config` - a directory that holds your project configuration. The `config/config.exs` file is the main entry point for your configuration. At the end of the `config/config.exs`, it imports environment specific configuration, which can be found in `config/dev.exs`, `config/test.exs`, and `config/prod.exs`
+  * `config` - a directory that holds your project configuration. The `config/config.exs` file is the main entry point for your configuration. At the end of the `config/config.exs`, it imports environment specific configuration, which can be found in `config/dev.exs`, `config/test.exs`, and `config/prod.exs`.
 
-  * `deps` - a directory with all of our Mix dependencies. You can find all dependencies listed in the `mix.exs` file, inside the `def deps do` function definition. This directory must not be checked into version control and it can be removed at any time. Removing it will force Mix to download all deps from scratch
+  * `deps` - a directory with all of our Mix dependencies. You can find all dependencies listed in the `mix.exs` file, inside the `def deps do` function definition. This directory must not be checked into version control and it can be removed at any time. Removing it will force Mix to download all deps from scratch.
 
-  * `lib` - a directory that holds your application source code. This directory is broken into two subdirectories, `lib/hello` and `lib/hello_web`. The `lib/hello` directory will be responsible to host all of your business logic and business domain. It typically interacts directly with the database - it is the "Model" in Model-View-Controller (MVC) architecture. `lib/hello_web` is responsible for exposing your business domain to the world, in this case, through a web application. It holds both the View and Controller from MVC. We will discuss the contents of these directories with more detail in the next sections
+  * `lib` - a directory that holds your application source code. This directory is broken into two subdirectories, `lib/hello` and `lib/hello_web`. The `lib/hello` directory will be responsible to host all of your business logic and business domain. It typically interacts directly with the database - it is the "Model" in Model-View-Controller (MVC) architecture. `lib/hello_web` is responsible for exposing your business domain to the world, in this case, through a web application. It holds both the View and Controller from MVC. We will discuss the contents of these directories with more detail in the next sections.
 
-  * `priv` - a directory that keeps all assets that are necessary in production but are not directly part of your source code. You typically keep database scripts, translation files, and more in here
+  * `priv` - a directory that keeps all assets that are necessary in production but are not directly part of your source code. You typically keep database scripts, translation files, and more in here.  Built static assets, sourced from the `assets` directory, are also served from here by default.
 
-  * `test` - a directory with all of our application tests. It often mirrors the same structure found in `lib`
+  * `test` - a directory with all of our application tests. It often mirrors the same structure found in `lib`.
 
 ## The lib/hello directory
 
@@ -113,3 +113,13 @@ Besides the directories mentioned, `lib/hello_web` has four files at its root. `
 Through _Telemetry_, Phoenix is able to collect metrics and send monitoring events of your application. The `lib/hello_web/telemetry.ex` file defines the supervisor responsible for managing the telemetry processes. You can find more information on this topic in the [Telemetry guide](telemetry.html).
 
 Finally, there is a `lib/hello_web/gettext.ex` file which provides internationalization through [Gettext](https://hexdocs.pm/gettext/Gettext.html). If you are not worried about internationalization, you can safely skip this file and its contents.
+
+## The assets directory
+
+The `assets` directory contains everything related to front-end assets, such as JavaScript, CSS, static images and more. It is typically handled by the [npm] tool. Phoenix developers typically only need to run `npm install` inside the assets directory. Everything else is managed by Phoenix.
+
+A **default** Phoenix application includes a `webpack.config.js` capable of processing your front-end assets and staging them in the `priv/static` folder, where they may be served by the [Plug.Static] plug configured in `lib/hello_web/endpoint.ex`.  When running in dev mode (`MIX_ENV=dev`), Phoenix watches for any changes you make in the `assets` directory, and then takes care of updating your front end application in your browser as you work.
+
+**NB:** When you first create your Phoenix app using `mix phx.new` it is possible to specify options that will affect the presence and layout of the `assets` directory.  In fact Phoenix apps don't require you have a front-end at all (handy if you're writing an API for example).  For more information you can run `mix help phx.new` or see the documentation in [Mix tasks](mix_tasks.html).
+
+[npm]: https://www.npmjs.com/package/npm
diff --git a/guides/ecto.md b/guides/ecto.md
index 1d0628dc4..271224950 100644
--- a/guides/ecto.md
+++ b/guides/ecto.md
@@ -532,10 +532,7 @@ defmodule HelloPhoenix.MixProject do
       {:phoenix_ecto, "~> 4.0"},
       {:ecto_sql, "~> 3.5"},
       {:myxql, ">= 0.0.0"},
-      {:phoenix_html, "~> 2.11"},
-      {:phoenix_live_reload, "~> 1.2", only: :dev},
-      {:gettext, "~> 0.11"},
-      {:plug_cowboy, "~> 2.0"}
+      ...
     ]
   end
 end
diff --git a/guides/mix_tasks.md b/guides/mix_tasks.md
index 5052e7a21..b65f325ad 100644
--- a/guides/mix_tasks.md
+++ b/guides/mix_tasks.md
@@ -1,13 +1,13 @@
-# Mix Tasks
+# Mix tasks
 
-There are currently a number of built-in Phoenix-specific and Ecto-specific mix tasks available to us within a newly-generated application. We can also create our own application specific tasks.
+There are currently a number of built-in Phoenix-specific and Ecto-specific [Mix tasks](`Mix.Task`) available to us within a newly-generated application. We can also create our own application specific tasks.
 
 > Note to learn more about `mix`, you can read Elixir's official [Introduction to Mix](https://elixir-lang.org/getting-started/mix-otp/introduction-to-mix.html).
 
 ## Phoenix tasks
 
 ```console
-➜ mix help --search "phx"
+$ mix help --search "phx"
 mix local.phx          # Updates the Phoenix project generator locally
 mix phx                # Prints Phoenix help information
 mix phx.digest         # Digests and compresses static files
@@ -35,7 +35,7 @@ We will cover all Phoenix Mix tasks, except `phx.new`, `phx.new.ecto`, and `phx.
 
 ### `mix phx.gen.html`
 
-Phoenix offers the ability to generate all the code to stand up a complete HTML resource - ecto migration, ecto context, controller with all the necessary actions, view, and templates. This can be a tremendous time saver. Let's take a look at how to make this happen.
+Phoenix offers the ability to generate all the code to stand up a complete HTML resource — Ecto migration, Ecto context, controller with all the necessary actions, view, and templates. This can be a tremendous time saver. Let's take a look at how to make this happen.
 
 The `mix phx.gen.html` task takes a number of arguments, the module name of the context, the module name of the schema, the resource name, and a list of column_name:type attributes. The module name we pass in must conform to the Elixir rules of module naming, following proper capitalization.
 
@@ -57,7 +57,7 @@ $ mix phx.gen.html Blog Post posts body:string word_count:integer
 * injecting test/hello/blog/blog_test.exs
 ```
 
-When `mix phx.gen.html` is done creating files, it helpfully tells us that we need to add a line to our router file as well as run our ecto migrations.
+When `mix phx.gen.html` is done creating files, it helpfully tells us that we need to add a line to our router file as well as run our Ecto migrations.
 
 ```console
 Add the resource to your browser scope in lib/hello_web/router.ex:
@@ -101,7 +101,7 @@ Add the resource to your browser scope in lib/hello_web/router.ex:
     resources "/posts", PostController
 ```
 
-Similarly - if we want a context created without a schema for our resource we can use the `--no-schema` flag.
+Similarly, if we want a context created without a schema for our resource we can use the `--no-schema` flag.
 
 ```console
 $ mix phx.gen.html Blog Post posts body:string word_count:integer --no-schema
@@ -123,7 +123,7 @@ It will tell us we need to add a line to our router file, but since we skipped t
 
 ### `mix phx.gen.json`
 
-Phoenix also offers the ability to generate all the code to stand up a complete JSON resource - ecto migration, ecto schema, controller with all the necessary actions and view. This command will not create any template for the app.
+Phoenix also offers the ability to generate all the code to stand up a complete JSON resource — Ecto migration, Ecto schema, controller with all the necessary actions and view. This command will not create any template for the app.
 
 The `mix phx.gen.json` task takes a number of arguments, the module name of the context, the module name of the schema, the resource name, and a list of column_name:type attributes. The module name we pass in must conform to the Elixir rules of module naming, following proper capitalization.
 
@@ -142,7 +142,7 @@ $ mix phx.gen.json Blog Post posts title:string content:string
 * injecting test/hello/blog/blog_test.exs
 ```
 
-When `mix phx.gen.json` is done creating files, it helpfully tells us that we need to add a line to our router file as well as run our ecto migrations.
+When `mix phx.gen.json` is done creating files, it helpfully tells us that we need to add a line to our router file as well as run our Ecto migrations.
 
 ```console
 Add the resource to your :api scope in lib/hello_web/router.ex:
@@ -168,7 +168,7 @@ warning: function HelloWeb.Router.Helpers.post_path/3 is undefined or private
 
 ### `mix phx.gen.context`
 
-If we don't need a complete HTML/JSON resource and instead are only interested in a context, we can use the `mix phx.gen.context` task. It will generate a context, a schema, a migration and a test case.
+If we don't need a complete HTML/JSON resource and only need a context, we can use the `mix phx.gen.context` task. It will generate a context, a schema, a migration and a test case.
 
 The `mix phx.gen.context` task takes a number of arguments, the module name of the context, the module name of the schema, the resource name, and a list of column_name:type attributes.
 
@@ -207,7 +207,7 @@ $ mix phx.gen.schema Accounts.Credential credentials email:string:unique user_id
 
 ### `mix phx.gen.auth`
 
-Phoenix also offers the ability to generate all of the code to stand up a complete authentication system - ecto migration, phoenix context, controllers, templates, etc. This can be a huge time saver, allowing you to quickly add authentication to your system and shift your focus back to the primary problems your application is trying to solve.
+Phoenix also offers the ability to generate all of the code to stand up a complete authentication system — Ecto migration, phoenix context, controllers, templates, etc. This can be a huge time saver, allowing you to quickly add authentication to your system and shift your focus back to the primary problems your application is trying to solve.
 
 The `mix phx.gen.auth` task takes the following arguments: the module name of the context, the module name of the schema, and a plural version of the schema name used to generate database tables and route helpers.
 
@@ -258,7 +258,7 @@ $ mix phx.gen.auth Accounts User users
 * injecting lib/hello_web/templates/layout/app.html.eex
 ```
 
-When `mix phx.gen.auth` is done creating files, it helpfully tells us that we need to re-fetch our dependencies as well as run our ecto migrations.
+When `mix phx.gen.auth` is done creating files, it helpfully tells us that we need to re-fetch our dependencies as well as run our Ecto migrations.
 
 ```console
 Please re-fetch your dependencies with the following command:
@@ -270,11 +270,11 @@ Remember to update your repository by running migrations:
   $ mix ecto.migrate
 ```
 
-A more complete walk-through of how to get started with this generator is available in the [`mix phx.gen.auth` Guide](mix_phx_gen_auth.html).
+A more complete walk-through of how to get started with this generator is available in the [`mix phx.gen.auth` authentication guide](mix_phx_gen_auth.html).
 
 ### `mix phx.gen.channel`
 
-This task will generate a basic Phoenix channel as well a test case for it. It takes the module name for the channel as argument:
+This task will generate a basic Phoenix channel as well a test case for it. It takes the module name for the channel as the only one argument:
 
 ```console
 $ mix phx.gen.channel Room
@@ -292,7 +292,7 @@ Add the channel to your `lib/hello_web/channels/user_socket.ex` handler, for exa
 
 ### `mix phx.gen.presence`
 
-This task will generate a Presence tracker. The module name can be passed as an argument,
+This task will generate a presence tracker. The module name can be passed as an argument,
 `Presence` is used if no module name is passed.
 
 ```console
@@ -302,7 +302,7 @@ $ lib/hello_web/channels/presence.ex
 
 ### `mix phx.routes`
 
-This task has a single purpose, to show us all the routes defined for a given router. We saw it used extensively in the [Routing Guide](routing.html).
+This task has a single purpose, to show us all the routes defined for a given router. We saw it used extensively in the [routing guide](routing.html).
 
 If we don't specify a router for this task, it will default to the router Phoenix generated for us.
 
@@ -325,13 +325,13 @@ This is the task we use to get our application running. It takes no arguments at
 $ mix phx.server
 [info] Running TaskTesterWeb.Endpoint with Cowboy on port 4000 (http)
 ```
-It silently ignores our `DoesNotExist` argument.
+It will silently ignore our `DoesNotExist` argument:
 
 ```console
 $ mix phx.server DoesNotExist
 [info] Running TaskTesterWeb.Endpoint with Cowboy on port 4000 (http)
 ```
-If we would like to start our application and also have an `iex` session open to it, we can run the mix task within `iex` like this, `iex -S mix phx.server`.
+If we would like to start our application and also have an `IEx` session open to it, we can run the Mix task within `iex` like this, `iex -S mix phx.server`.
 
 ```console
 $ iex -S mix phx.server
@@ -346,11 +346,11 @@ iex(1)>
 
 This task does two things, it creates a digest for our static assets and then compresses them.
 
-"Digest" here refers to an MD5 digest of the contents of an asset which gets added to the filename of that asset. This creates a sort of "fingerprint" for it. If the digest doesn't change, browsers and CDNs will use a cached version. If it does change, they will re-fetch the new version.
+"Digest" here refers to an MD5 digest of the contents of an asset which gets added to the filename of that asset. This creates a sort of fingerprint for it. If the digest doesn't change, browsers and CDNs will use a cached version. If it does change, they will re-fetch the new version.
 
 Before we run this task let's inspect the contents of two directories in our hello application.
 
-First `priv/static` which should look similar to this:
+First `priv/static/` which should look similar to this:
 
 ```console
 ├── images
@@ -376,7 +376,7 @@ $ mix phx.digest
 Check your digested files at 'priv/static'.
 ```
 
-We can now do as the task suggests and inspect the contents of `priv/static` directory. We'll see that all files from `assets/` have been copied over to `priv/static` and also each file now has a couple of versions. Those versions are:
+We can now do as the task suggests and inspect the contents of `priv/static/` directory. We'll see that all files from `assets/` have been copied over to `priv/static/` and also each file now has a couple of versions. Those versions are:
 
 * the original file
 * a compressed file with gzip
@@ -392,13 +392,13 @@ config :phoenix, :gzippable_exts, ~w(.js .css)
 > Note: We can specify a different output folder where `mix phx.digest` will put processed files. The first argument is the path where the static files are located.
 
 ```console
-$ mix phx.digest priv/static -o www/public
-Check your digested files at 'www/public'.
+$ mix phx.digest priv/static/ -o www/public/
+Check your digested files at 'www/public/'
 ```
 
 ## Ecto tasks
 
-Newly generated Phoenix applications now include ecto and postgrex as dependencies by default (which is to say, unless we use `mix phx.new` with the `--no-ecto` flag). With those dependencies come mix tasks to take care of common ecto operations. Let's see which tasks we get out of the box.
+Newly generated Phoenix applications now include Ecto and Postgrex as dependencies by default (which is to say, unless we use `mix phx.new` with the `--no-ecto` flag). With those dependencies come Mix tasks to take care of common Ecto operations. Let's see which tasks we get out of the box.
 
 ```console
 $ mix help --search "ecto"
@@ -418,7 +418,7 @@ Note: We can run any of the tasks above with the `--no-start` flag to execute th
 
 ### `mix ecto.create`
 
-This task will create the database specified in our repo. By default it will look for the repo named after our application (the one generated with our app unless we opted out of ecto), but we can pass in another repo if we want.
+This task will create the database specified in our repo. By default it will look for the repo named after our application (the one generated with our app unless we opted out of Ecto), but we can pass in another repo if we want.
 
 Here's what it looks like in action.
 
@@ -487,7 +487,7 @@ The database for OurCustom.Repo has been created.
 
 ### `mix ecto.drop`
 
-This task will drop the database specified in our repo. By default it will look for the repo named after our application (the one generated with our app unless we opted out of ecto). It will not prompt us to check if we're sure we want to drop the db, so do exercise caution.
+This task will drop the database specified in our repo. By default it will look for the repo named after our application (the one generated with our app unless we opted out of Ecto). It will not prompt us to check if we're sure we want to drop the database, so do exercise caution.
 
 ```console
 $ mix ecto.drop
@@ -553,7 +553,7 @@ children = [
 
 ### `mix ecto.gen.migration`
 
-Migrations are a programmatic, repeatable way to affect changes to a database schema. Migrations are also just modules, and we can create them with the `ecto.gen.migration` task. Let's walk through the steps to create a migration for a new comments table.
+Migrations are a programmatic, repeatable way to affect changes to a database schema. Migrations are also just modules, and we can create them with the [`ecto.gen.migration`](`mix ecto.gen.migration`) task. Let's walk through the steps to create a migration for a new comments table.
 
 We simply need to invoke the task with a `snake_case` version of the module name that we want. Preferably, the name will describe what we want the migration to do.
 
@@ -601,7 +601,7 @@ $ mix ecto.gen.migration -r OurCustom.Repo add_users
 ```
 
 For more information on how to modify your database schema please refer to the
-Ecto's migration DSL [ecto migration docs](https://hexdocs.pm/ecto_sql/Ecto.Migration.html).
+[Ecto's migration DSL docs](https://hexdocs.pm/ecto_sql/Ecto.Migration.html).
 For example, to alter an existing schema see the documentation on Ecto’s
 [`alter/2`](https://hexdocs.pm/ecto_sql/Ecto.Migration.html#alter/2) function.
 
@@ -631,7 +631,7 @@ version        |     inserted_at
 (2 rows)
 ```
 
-When we roll back a migration, `ecto.rollback` will remove the record representing this migration from `schema_migrations`.
+When we roll back a migration, [`ecto.rollback`](#mix-ecto-rollback) will remove the record representing this migration from `schema_migrations`.
 
 By default, `ecto.migrate` will execute all pending migrations. We can exercise more control over which migrations we run by specifying some options when we run the task.
 
@@ -661,7 +661,7 @@ mix ecto.migrate --to 20150317170448
 
 ### `mix ecto.rollback`
 
-The `ecto.rollback` task will reverse the last migration we have run, undoing the schema changes. `ecto.migrate` and `ecto.rollback` are mirror images of each other.
+The [`ecto.rollback`](`mix ecto.rollback`) task will reverse the last migration we have run, undoing the schema changes. [`ecto.migrate`](#mix-ecto-migrate) and `ecto.rollback` are mirror images of each other.
 
 ```console
 $ mix ecto.rollback
@@ -674,12 +674,12 @@ $ mix ecto.rollback
 
 ## Creating our own Mix task
 
-As we've seen throughout this guide, both mix itself and the dependencies we bring in to our application provide a number of really useful tasks for free. Since neither of these could possibly anticipate all our individual application's needs, mix allows us to create our own custom tasks. That's exactly what we are going to do now.
+As we've seen throughout this guide, both Mix itself and the dependencies we bring in to our application provide a number of really useful tasks for free. Since neither of these could possibly anticipate all our individual application's needs, Mix allows us to create our own custom tasks. That's exactly what we are going to do now.
 
-The first thing we need to do is create a `mix/tasks` directory inside of `lib`. This is where any of our application specific mix tasks will go.
+The first thing we need to do is create a `mix/tasks/` directory inside of `lib/`. This is where any of our application specific Mix tasks will go.
 
 ```console
-$ mkdir -p lib/mix/tasks
+$ mkdir -p lib/mix/tasks/
 ```
 
 Inside that directory, let's create a new file, `hello.greeting.ex`, that looks like this.
@@ -691,7 +691,7 @@ defmodule Mix.Tasks.Hello.Greeting do
   @shortdoc "Sends a greeting to us from Hello Phoenix"
 
   @moduledoc """
-  This is where we would put any long form documentation or doctests.
+  This is where we would put any long form documentation and doctests.
   """
 
   def run(_args) do
@@ -702,18 +702,18 @@ defmodule Mix.Tasks.Hello.Greeting do
 end
 ```
 
-Let's take a quick look at the moving parts involved in a working mix task.
+Let's take a quick look at the moving parts involved in a working Mix task.
 
-The first thing we need to do is name our module. All tasks must be defined in `Mix.Tasks` namespace. We'd like to invoke this as `mix hello.greeting`, so we complete the module name with
+The first thing we need to do is name our module. All tasks must be defined in the `Mix.Tasks` namespace. We'd like to invoke this as `mix hello.greeting`, so we complete the module name with
 `Hello.Greeting`.
 
-The `use Mix.Task` line brings in functionality from Mix that makes this module behave as a mix task.
+The `use Mix.Task` line brings in functionality from Mix that makes this module [behave as a Mix task](`Mix.Task`).
 
 The `@shortdoc` module attribute holds a string which will describe our task when users invoke `mix help`.
 
 `@moduledoc` serves the same function that it does in any module. It's where we can put long-form documentation and doctests, if we have any.
 
-The `run/1` function is the critical heart of any Mix task. It's the function that does all the work when users invoke our task. In ours, all we do is send a greeting from our app, but we can implement our `run/1` function to do whatever we need it to. Note that `Mix.shell().info/1` is the preferred way to print text back out to the user.
+The [`run/1`](`c:Mix.Task.run/1`) function is the critical heart of any Mix task. It's the function that does all the work when users invoke our task. In ours, all we do is send a greeting from our app, but we can implement our `run/1` function to do whatever we need it to. Note that [`Mix.shell().info/1`](`Mix.shell/0`) is the preferred way to print text back out to the user.
 
 Of course, our task is just a module, so we can define other private functions as needed to support our `run/1` function.
 
@@ -743,13 +743,13 @@ Greetings from the Hello Phoenix Application!
 
 Indeed it does.
 
-If you want to make your new mix task to use your application's infrastructure, you need to make sure the application is started when mix task is being executed. This is particularly useful if you need to access your database from within the mix task. Thankfully, mix makes it really easy for us:
+If you want to make your new Mix task to use your application's infrastructure, you need to make sure the application is started when Mix task is being executed. This is particularly useful if you need to access your database from within the Mix task. Thankfully, Mix makes it really easy for us:
 
 ```elixir
-  . . .
   def run(_args) do
     Mix.Task.run("app.start")
     Mix.shell().info("Now I have access to Repo and other goodies!")
+    Mix.shell().info("Greetings from the Hello Phoenix Application!")    
   end
-  . . .
 ```
+
diff --git a/guides/views.md b/guides/views.md
index a178790b4..b720964d7 100644
--- a/guides/views.md
+++ b/guides/views.md
@@ -268,7 +268,6 @@ end
 ```
 
 The name used in assigns is determined from the view. For example `PageView` will use `%{page: page}` and `AuthorView` will use `%{author: author}`. This can be overridden with the `as` option. Let's assume that the author view uses `%{writer: writer}` instead of `%{author: author}`:
->>>>>>> ff14fd75 (Fix grammar. Remove article "the" before controllers and views.)
 
 ```elixir
 def render("page_with_authors.json", %{page: page}) do
diff --git a/installer/templates/phx_single/config/config.exs b/installer/templates/phx_single/config/config.exs
index 44ac95008..5ffdbae19 100644
--- a/installer/templates/phx_single/config/config.exs
+++ b/installer/templates/phx_single/config/config.exs
@@ -1,5 +1,5 @@
 # This file is responsible for configuring your application
-# and its dependencies with the aid of the Mix.Config module.
+# and its dependencies with the aid of the Config module.
 #
 # This configuration file is loaded before any dependency and
 # is restricted to this project.
diff --git a/installer/templates/phx_umbrella/config/config.exs b/installer/templates/phx_umbrella/config/config.exs
index 7163afb34..4b232332d 100644
--- a/installer/templates/phx_umbrella/config/config.exs
+++ b/installer/templates/phx_umbrella/config/config.exs
@@ -1,6 +1,6 @@
 # This file is responsible for configuring your umbrella
 # and **all applications** and their dependencies with the
-# help of Mix.Config.
+# help of the Config module.
 #
 # Note that all applications in your umbrella share the
 # same configuration and dependencies, which is why they
diff --git a/lib/mix/tasks/compile.phoenix.ex b/lib/mix/tasks/compile.phoenix.ex
index 010afcde4..a97a81c71 100644
--- a/lib/mix/tasks/compile.phoenix.ex
+++ b/lib/mix/tasks/compile.phoenix.ex
@@ -4,6 +4,11 @@ defmodule Mix.Tasks.Compile.Phoenix do
 
   @moduledoc """
   Compiles Phoenix source files that support code reloading.
+  
+  If you are using Elixir v1.11+ or later, there is no longer
+  a need to use this module as this functionality is now provided
+  by Elixir. Just remember to update `__phoenix_recompile__?` to
+  `__mix_recompile__?` in any module that may define it.
   """
 
   # TODO: Deprecate this module once we require Elixir v1.11+
diff --git a/lib/phoenix/code_reloader.ex b/lib/phoenix/code_reloader.ex
index b1b33211d..cfbb56264 100644
--- a/lib/phoenix/code_reloader.ex
+++ b/lib/phoenix/code_reloader.ex
@@ -2,18 +2,6 @@ defmodule Phoenix.CodeReloader do
   @moduledoc """
   A plug and module to handle automatic code reloading.
 
-  For each request, Phoenix goes through all modules and checks if any of
-  them implement a `__phoenix_recompile__?/0` function. If they do and
-  it returns true, the module source file is touched, forcing it to be
-  recompiled. For this functionality to work, Phoenix requires you to add
-  the `:phoenix` compiler to your list of compilers:
-
-      compilers: [:phoenix] ++ Mix.compilers()
-
-  This is useful, for example, to recompile modules that depend on external
-  systems, such as directories, databases, etc. Note if you simply depend on
-  external files, `@external_resource` annotation should be used.
-
   To avoid race conditions, all code reloads are funneled through a
   sequential call operation.
   """
diff --git a/mix.exs b/mix.exs
index d7ba09851..8755bb7f6 100644
--- a/mix.exs
+++ b/mix.exs
@@ -52,7 +52,7 @@ defmodule Phoenix.MixProject do
         stacktrace_depth: nil,
         filter_parameters: ["password"],
         serve_endpoints: false,
-        gzippable_exts: ~w(.js .css .txt .text .html .json .svg .eot .ttf),
+        gzippable_exts: ~w(.js .map .css .txt .text .html .json .svg .eot .ttf),
         static_compressors: [Phoenix.Digester.Gzip]
       ]
     ]
@@ -74,6 +74,7 @@ defmodule Phoenix.MixProject do
       # Docs dependencies (some for cross references)
       {:ex_doc, "~> 0.22", only: :docs},
       {:ecto, ">= 3.0.0", only: :docs},
+      {:ecto_sql, "~> 3.5", only: :docs},
       {:gettext, "~> 0.15.0", only: :docs},
       {:telemetry_poller, "~> 0.4", only: :docs},
       {:telemetry_metrics, "~> 0.4", only: :docs},
diff --git a/mix.lock b/mix.lock
index d333b9264..895029584 100644
--- a/mix.lock
+++ b/mix.lock
@@ -1,9 +1,12 @@
 %{
+  "connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"},
   "cowboy": {:hex, :cowboy, "2.7.0", "91ed100138a764355f43316b1d23d7ff6bdb0de4ea618cb5d8677c93a7a2f115", [:rebar3], [{:cowlib, "~> 2.8.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "04fd8c6a39edc6aaa9c26123009200fc61f92a3a94f3178c527b70b767c6e605"},
   "cowlib": {:hex, :cowlib, "2.8.0", "fd0ff1787db84ac415b8211573e9a30a3ebe71b5cbff7f720089972b2319c8a4", [:rebar3], [], "hexpm", "79f954a7021b302186a950a32869dbc185523d99d3e44ce430cd1f3289f41ed4"},
+  "db_connection": {:hex, :db_connection, "2.3.1", "4c9f3ed1ef37471cbdd2762d6655be11e38193904d9c5c1c9389f1b891a3088e", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm", "abaab61780dde30301d840417890bd9f74131041afd02174cf4e10635b3a63f5"},
   "decimal": {:hex, :decimal, "1.9.0", "83e8daf59631d632b171faabafb4a9f4242c514b0a06ba3df493951c08f64d07", [:mix], [], "hexpm", "b1f2343568eed6928f3e751cf2dffde95bfaa19dd95d09e8a9ea92ccfd6f7d85"},
   "earmark_parser": {:hex, :earmark_parser, "1.4.10", "6603d7a603b9c18d3d20db69921527f82ef09990885ed7525003c7fe7dc86c56", [:mix], [], "hexpm", "8e2d5370b732385db2c9b22215c3f59c84ac7dda7ed7e544d7c459496ae519c0"},
   "ecto": {:hex, :ecto, "3.5.5", "48219a991bb86daba6e38a1e64f8cea540cded58950ff38fbc8163e062281a07", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "98dd0e5e1de7f45beca6130d13116eae675db59adfa055fb79612406acf6f6f1"},
+  "ecto_sql": {:hex, :ecto_sql, "3.5.4", "a9e292c40bd79fff88885f95f1ecd7b2516e09aa99c7dd0201aa84c54d2358e4", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.5.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.3.0 or ~> 0.4.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "1fff1a28a898d7bbef263f1f3ea425b04ba9f33816d843238c84eff883347343"},
   "ex_doc": {:hex, :ex_doc, "0.23.0", "a069bc9b0bf8efe323ecde8c0d62afc13d308b1fa3d228b65bca5cf8703a529d", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "f5e2c4702468b2fd11b10d39416ddadd2fcdd173ba2a0285ebd92c39827a5a16"},
   "gettext": {:hex, :gettext, "0.15.0", "40a2b8ce33a80ced7727e36768499fc9286881c43ebafccae6bab731e2b2b8ce", [:mix], [], "hexpm", "d17ac3aa40835f7feb92913fcdf655edea59938fa8b25f5ce5d423e76a695c3b"},
   "jason": {:hex, :jason, "1.0.0", "0f7cfa9bdb23fed721ec05419bcee2b2c21a77e926bce0deda029b5adc716fe2", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "b96c400e04b7b765c0854c05a4966323e90c0d11fee0483b1567cda079abb205"},


Test patch:
diff --git a/test/phoenix/digester_test.exs b/test/phoenix/digester_test.exs
index 12cccaf8b..78594f2e6 100644
--- a/test/phoenix/digester_test.exs
+++ b/test/phoenix/digester_test.exs
@@ -24,6 +24,8 @@ defmodule Phoenix.DigesterTest do
       refute "phoenix.png.gz" in output_files
       assert "app.js" in output_files
       assert "app.js.gz" in output_files
+      assert "app.js.map" in output_files
+      assert "app.js.map.gz" in output_files
       assert "css/app.css" in output_files
       assert "css/app.css.gz" in output_files
       assert "manifest.json" in output_files