Laravel: Up & Running 中文版
  • Laravel Up and Running A Framework for Building Modern PHP Apps
  • 为什么是Laravel
    • 为什么使用框架
    • “自己写”
    • 一致性与灵活性
    • 简短PHP Web框架历史
      • Ruby on Rails
      • PHP框架的涌入
      • CodeIgniter的优劣
      • Laravel 1, 2,和 3
      • Laravel 4
      • Laravel 5
    • Laravel 特别之处
      • Laravel哲学
      • Laravel如何让开发者感到幸福
      • Laravel 社区
    • 是如何运作的
    • 为什么是Laravel
  • 创建Laravel开发环境
    • 系统要求
    • Composer
    • 本地开发环境
      • Laravel Valet
      • Laravel Homestead
    • 创建一个新的Laravel项目
      • 使用Laravel安装工具安装Laravel
      • 使用Composer的create-project功能安装Laravel
      • Lambo:一款增强的"Laravel New"工具
    • Laravel的目录结构
      • 文件夹
      • 其他零散文件
    • 配置
      • .env文件
    • 运行
    • 测试
    • 总结
  • 路由与控制器
    • MVC HTTP和REST简介
      • 什么是MVC
      • HTTP verbs
      • 什么是REST
    • 定义路由
      • Route Verbs
      • 处理路由
      • 路由参数
      • 路由命名
    • 路由组
      • 中间件
        • 在控制器内应用中间件
        • 频率限制
      • 路径前缀
      • 兜底路由
      • 子域路由
      • 命名空间前缀
      • 名称前缀
    • 路由签名
      • 添加签名
      • 修改路由可以访问签名链接
    • 视图
      • 直接使用Route::view()返回简单路由
      • 使用View Composer在视图间共享变量
    • 控制器
      • 获取用户输入
      • 将依赖注入到控制器
      • 资源控制器
      • API 资源控制器
      • 单动作控制器
    • 路由模型绑定
      • 隐式路由模型绑定
      • 自定义路由模型绑定
    • 路由缓存
    • 表单请求方法伪造
      • Laravel内的HTTP verb
      • HTML 表单中的HTTP方法伪造
    • CSRF保护
    • 重定向
      • redirect()->to()
      • redirect()->route()
      • redirect()->back()
      • 其他重定向方法
      • redirect()->with()
    • 关于请求
    • 自定义响应
      • response()->make()
      • response()->json() 和 ->jsonp()
      • response()->download(), ->streamDownload(), 和 ->file()
    • 测试
    • 总结
  • Blade 模板引擎
    • 输出数据
    • 控制结构
      • 条件
      • 循环
    • 模板继承
      • 包含视图
      • 使用堆栈
      • 使用组件与插槽
    • 视图Composer和服务注入
      • 使用视图composers绑定数据到视图
      • Blade 服务注入
    • 自定义Blade指令
      • 自定义指令传参
      • 示例:多租户的自定义Blade指令
      • 更简单的if语句自定义指令
    • 测试
    • 总结
  • 数据库和Eloquent
    • 配置
      • 数据库连接
      • 其他数据库配置选项
      • 定义迁移
        • 创建一个迁移
        • 创建表格
        • 创建字段
        • 构建额外属性
        • 丢弃表格
        • 修改字段
        • 索引和外键
      • 运行迁移
    • 填充
      • 创建一个填充
      • 模型工厂
    • 查询器
      • DB facade的基础用法
      • 原生SQL
      • 使用查询器
      • 事务
    • Eloquent介绍
      • 创建和定义Eloquent模型
      • 使用Eloquent检索数据
      • 使用Eloquent插入和更新
      • 使用Eloquent删除
      • 作用域
      • 使用访问,赋值和属性转换自定义字段
      • Eloquent集合
      • Eloquent序列化
      • Eloquent关系
      • 子记录更新父记录时间戳
    • Eloquent事件
    • 测试
    • 总结
  • 前端组件
    • Laravel 混合
      • Mix 文件夹结构
      • 运行Mix
      • Mix提供了什么
    • 前端预设和授权脚手架
      • 前端预设
    • 分页
    • 信息包
      • 命名错误包
    • 字符串助手,多元化和本地化
      • 字符串助手和多元化
      • 本地化
    • 测试
      • 测试Message和错误包
      • 翻译和本地化
    • 总结
  • 收集和处理用户数据
    • 注入一个请求对象
      • $request->all()
      • $request->except()和$request->only()
      • $request->has()
      • $request->input()
      • $request->method() 和->isMethod()
      • 数组输入
      • JSON 输入($request->json())
    • 路由数据
      • 来自请求
      • 来自路由参数
    • 上传文件
    • 验证
      • Request对象上的validate()
      • 手动验证
      • 自定义验证规则
      • 显示验证错误信息
    • 表单请求
      • 创建一个表单请求
      • 使用表单请求
    • Eloquent 模型批量赋值
    • {{ 与 {!!
    • 测试
    • 总结
  • Artisan 和 Tinker
    • Artisan 介绍
    • 基础Artisan命令
      • 选项
      • 分组的命令
    • 编写自定义Artisan命令
      • 一个简单的命令
      • 参数和选项
      • 使用输入
      • 提示
      • 输出
      • 基于闭包的命令
    • 在普通代码调用Artisan命令
    • Tinker
    • Laravel Dump 服务
    • 测试
    • 总结
  • 用户认证与授权
    • 用户模型与迁移
    • 使用auth()全局辅助和Auth Facade
    • 认证控制器
      • RegisterController
      • LoginController
      • ResetPasswordController
      • ForgotPasswordController
      • VerificationController
    • Auth::routes()
    • 认证脚手架
    • ”记住我“
    • 手动认证用户
    • 手动登出用户
    • 认证中间件
    • 邮箱验证
    • Blade认证指令
    • 守卫
      • 更改默认守卫
      • 不更改默认使用其他守卫
      • 添加新守卫
      • 闭包请求守卫
      • 创建一个自定义用户提供者
      • 非关系数据库的自定义用户提供者
    • 认证事件
    • 授权(ACL)和角色
      • 定义授权角色
      • Gate Facade(注入Gate)
      • 资源Gates
      • 授权中间件
      • 控制器授权
      • 检查用户实例
      • Blade检查
      • 拦截检查
      • 策略
    • 测试
    • 总结
  • 请求,响应,和中间件
    • Laravel的请求生命周期
      • 启动应用程序
      • 服务提供者
    • 请求对象
      • 在Laravel获取一个请求对象
      • 获取请求的基本信息
    • 响应对象
      • 在控制器内使用和创建响应对象
      • 序列化响应类型
    • Laravel和中间件
      • 中间件介绍
      • 创建自定义中间件
      • 绑定中间件
      • 给中间件传参
    • 可信代理
    • 测试
    • 总结
  • 容器
    • 依赖注入简介
    • 依赖注入与Laravel
    • app()全局辅助函数
    • 如何连接容器
    • 绑定类到容器
      • 绑定到闭包
      • 绑定到单例,Aliases和实例
      • 绑定具体实例到接口
      • 上下文绑定
    • Laravel框架内的构造注入
    • 方法注入
    • Facades和容器
      • Facade是如何工作的
      • 实时Facades
    • 服务提供者
    • 测试
    • 总结
  • 测试
  • 编写APIs
    • REST基础-JSON APIs
    • 控制器组织和JSON返回
    • 读取和发送Headers
      • 在Laravel中发送响应头
      • 在Laravel中读取请求头
    • Eloquent 分页
    • 排序和过滤
      • 排序你的API 结果
      • 过滤你的API结果
    • 转换结果
    • API 资源
      • 创建一个资源类
      • 资源集合
      • 嵌套关系
      • 对API资源使用分页
      • 有条件地应用属性
      • API资源的更多自定义
    • API 认证和Laravel Passport
      • OAuth 2.0 简介
      • 安装Passport
      • Passport的API
      • Passport的有效授权类型
      • 使用Passport API和vue组件管理客户端和令牌
      • Passport 作用域
      • 部署Passport
    • API Token认证
    • 自定义404响应
      • 触发回退路由
    • 测试
    • 总结
  • 存储和检索
Powered by GitBook
On this page

Was this helpful?

  1. 前端组件
  2. Laravel 混合

Mix提供了什么

我已经提到Mix可以使用sass、less和/或postcss预处理您的css。它还可以连接任何类型的文件,压缩它们,重命名它们,并复制它们,还可以复制整个目录或单个文件

此外,Mix可以处理现代风格javascript,并提供自动重新编译、连接和压缩JavaScript。它使browsersync、hmr和版本控制变得容易,并且有许多插件可用于其他常见的构建场景。

混合文档涵盖了所有这些选项以及更多选项,但是我们将在下面的部分中讨论一些特定的用例。

源代码图

如果你不熟悉源代码视图,它实际是告知浏览器可以检查你的源代码

默认情况下,mix不会为文件生成源代码图。但是您可以通过在Mix调用之后链式调用sourcemaps()方法来启用它们,如例6-3所示。

Example 6-3. Enabling source maps in Mix
let mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js').sourceMaps();

一旦你这么配置了Mix,你可以看到在每个源文件旁生成了一个名为{file‐name}.map的文件

如果没有源代码映射,如果您使用浏览器的开发工具检查特定的CSS规则或JavaScript操作,您将看到一大堆已编译的代码。使用源映射,您的浏览器可以精确定位源文件的确切行,无论是sass、javascript还是其他什么,都可以生成您要检查的规则。

前置和后置处理器

我们已经介绍过Sass和Less,Mix也可以处理Sytlus(如示例6-4)你也可以在其他样式后链式调用PostCSS(示例6-5)

Example 6-4. Preprocessing CSS with Stylus
mix.stylus('resources/stylus/app.styl', 'public/css');
Example 6-5. Post-processing CSS with PostCSS
mix.sass('resources/sass/app.scss', 'public/css')
   .options({
        postCss: [
            require('postcss-css-variables')()
] });

预处理CSS

如果对预处理不了解,有这么一个命令,它会抓取你的CSS文件,链接他们然后输出到public/css目录,有这么几种操作,你可以查看示例6-6

Example 6-6. Combining stylesheets with Mix
// Combines all files from resources/css
mix.styles('resources/css', 'public/css/all.css');
// Combines files from resources/css
mix.styles([
    'resources/css/normalize.css',
    'resources/css/app.css'
], 'public/css/all.css');

链接javascript

处理javascript与处理css非常类似,可以查看示例6-7

Example 6-7. Combining JavaScript files with Mix
let mix = require('laravel-mix');
// Combines all files from resources/js
mix.scripts('resources/js', 'public/js/all.js');
// Combines files from resources/js
mix.scripts([
    'resources/js/normalize.js',
    'resources/js/app.js'
], 'public/js/all.js');

预处理javascript

如果你想预处理Javascript-如例子,为将ES6代码编译成纯Javascript-Mix可以使用Webpack很轻松的做到.如示例6-8

Example 6-8. Processing JavaScript files in Mix with Webpack
let mix = require('laravel-mix'); 
mix.js('resources/js/app.js', 'public/js');

这段脚本会把resource/js下面的js文件输出到public/js下面。

通过在项目根目录中创建webpack.config.js文件,可以使用webpack更多特性。

拷贝文件或者目录

想要拷贝文件或者目录,可以使用copy()或者Directory()方法。

 mix.copy('node_modules/pkgname/dist/style.css', 'public/css/pkgname.css');
 mix.copyDirectory('source/images', 'public/images');

版本

来自Steve Souders的”快速网站响应“已经深入到我们的日常开发中。我们将脚本移到页脚,减少HTTP请求以及更多。但是通常并没有认识到这些想法的起源。

Steve的一个提示仍然很少实现,这就是在资源(脚本,样式和图像)上设置非常长的缓存时间。 这样做意味着您的服务器获取最新版本资源的请求将会减少。 但这也意味着用户极有可能使用的是缓存版本的资源,这是过时的。

解决方案是版本控制。每次运行构建脚本时,在每个资产的文件名中附加一个唯一的哈希,然后该唯一文件将被无限期缓存,或者至少在下一个构建之前缓存。

怎么做?首先,您需要得到生成的哈希并将其附加到文件名中。您还需要更新每个构建的视图,以引用新的文件名。

你可能猜到了,Mix为了做了这些,这是难以置信的简单。有两个组件:Mix的版本控制和mix()php辅助函数。首先,您可以通过运行mix.version()来对资产进行版本设置,如示例6-9所示。

Example 6-9. mix.version
let mix = require('laravel-mix');
mix.sass('resources/sass/app.scss', 'public/css')
    .version();

生成的文件版本没有什么不同,只是名为app.css并存放在public/css中。

使用查询参数进行版本控制

在Laravel中处理版本控制的方式与传统版本控制略有不同,因为版本控制附加了查询参数,而不是通过修改文件名。 它仍然以相同的方式运行,因为浏览器将其作为“新”文件读取,但它处理一些带有缓存和负载平衡器的边缘情况

接着,在视图内使用PHP mix()辅助函数引用资源,如示例6-10

Example 6-10. Using the mix() helper in views
<link rel="stylesheet" href="{{ mix("css/app.css") }}">
// Will output something like:
<link rel="stylesheet" href="/css/app.css?id=5ee7141a759a5fb7377a">

Mix 版本控制的背后

Mix生成名为public/mix-manifest.json的文件,它存储了mix()用于查找的信息,如下是mix-manifest.json示例

{
"/css/app.css": "/css/app.css?id=4151cf6261b95f07227e"
}

Vue和React

Mix可以处理Vue和React组件,Mix默认调用Vue,你也可以替换成React

mix.react('resources/js/app.js', 'public/js');

如果您查看默认的Laravel示例app.js及其导入的组件(示例6-11),您将看到您不必执行任何特殊操作来使用Vue组件。 在你的app.js中简单调用mix即可

Example 6-11. App.js configured to work with Vue
window.Vue = require('vue');
Vue.component('example-component', require('./components/ExampleComponent.vue'));
const app = new Vue({ el: '#app'
});

如果你想切换到react(),你可以在组件内这么写

require('./components/Example');

预设还引入了Axios, Lodash, 和 Popper.js,因此你不需要在Vue或者React搭建上浪费时间。

热模块替换

如果你正在使用Vue或者React编写组件,你希望在每次构建工具重新编译组件时刷新页面,如果你正在使用Mix,它会调用Browsersync来重载页面。

这很好,但是如果您正在使用单页应用程序(SPA),这意味着您已经重新启动应用程序; 当你浏览应用程序时,刷新会清除你建立的状态。

热模块更换(HMR,有时称为热重新加载)解决了这个问题。设置起来并不总是那么容易,但是Mix是可以实现的。HMR的工作原理就好像你教过browsersync不要重新加载整个文件,而是只重新加载你更改的代码。这意味着您可以将更新后的代码注入到浏览器中,但仍然可以保留之前的状态。

要使用HMR,你需要运行npm run hot,而不是npm run watch,为了保证正常运行,你需要确认<script>引用正确版本的javascript,实际上,Mix会在localhost:8080启动一个Node服务,所以如果你的<script>指向错误版本,HMR将不会运行。

要实现请使用mix()辅助函数引用脚本,辅助函数会帮你处理在localhost:8080下的HMR和正常的开发模式的引用问题。

<body>
    <div id="app"></div>
    <script src="{{ mix('js/app.js') }}"></script>
</body>

Vendor抽取

常见的前端模式最终会生成一个CSS文件和一个JavaScript文件,其中包含项目的应用程序特定代码和所有依赖项的代码。

这意味着vendor文件更新需要将整个文件都更新或者缓存,这将浪费加载时间。

Mix可以很容易的从应用依赖中提取依赖成一个vendor.js,只需要在js()后调用extract()方法,如示例6-12

Example 6-12. Extracting a vendor library into a separate file
mix.js('resources/js/app.js', 'public/js')
    .extract(['vue'])

这将输出两个文件:manifest.js用于描述如何加载依赖,vendor.js,它包含特定的vendor代码。

按照循序加载这些文件很重要,首先是manifest.js, 然后是vendor.js, 最后是 app.js

在mix 4.0+中使用extract()提取所有依赖项

如果项目使用的是LaravelMix4.0或更高版本,则可以不带参数调用extract()方法。这将提取应用程序的整个依赖项列表

<script src="{{ mix('js/manifest.js') }}"></script>
<script src="{{ mix('js/vendor.js') }}"></script>
<script src="{{ mix('js/app.js') }}"></script>

Mix中的环境变量

如示例6-13,如果你在.env内添加以MIX__开头的环境变量,那么你可以在Mix-compiled文件中通过process.env.ENV_VAR_NAME来访问这些变量.

Example 6-13. Using .env variables in Mix-compiled JavaScript
# In your .env file
MIX_BUGSNAG_KEY=lj12389g08bq1234
MIX_APP_NAME="Your Best App Now"
// In Mix-compiled files
process.env.MIX_BUGSNAG_KEY // For example, this code:
console.log("Welcome to " + process.env.MIX_APP_NAME); 
// Will compile down to this:
console.log("Welcome to " + "Your Best App Now");

你也可以使用Node的dotnev包在Webpack配置内访问这些变量,如示例6-14

Example 6-14. Using .env variables in Webpack configuration files
// webpack.mix.js
let mix = require('laravel-mix'); 
require('dotenv').config();
let isProduction = process.env.MIX_ENV === "production";
Previous运行MixNext前端预设和授权脚手架

Last updated 5 years ago

Was this helpful?

如果你在HTTPS上开发你的应用,例如你运行valet secure,你的资源必须通过HTTPS链接,这有些棘手,最好查看

HMR docs