Laravel 5.8 集合 vue-element-admin 踩坑记

创建 Laravel 项目

按照官方文档,进行安装:

composer create-project --prefer-dist laravel/laravel laravel-vue-admin

下载 vue-element-admin

$ git clone https://github.com/PanJiaChen/vue-element-admin.git

初始化package

将 vue-element-admin 中 package.json 中的 dependenciesdevDependencies 合并到 Laravel 的 package.json 中。

版本以 vue-element-admin 的版本为准

复制文件

将 vue-element-admin 中整个 src 目录下的文件复制到 laravel 项目中的 resources/backend 目录中。

安装前端依赖

$ npm install

添加打包语句

修改 webpack.mix.js 为:

const mix = require('laravel-mix');

mix.js('resources/js/app.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css');

mix.js('resources/backend/main.js', 'public/js')

添加入口文件

resources/views 中添加 admin.blade.php 视图文件,代码如下:

<!doctype html>
<html lang="{{ app()->getLocale() }}">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <title>title</title>
</head>
<body>
<div id="app"></div>
<script src="{{ mix('/js/main.js') }}"></script>
</body>
</html>

配置路由映射

routes/web.php 文件中添加如下路由:

Route::get('/admin', function () {
    return view('admin');
});

配置nginx

启动

$ npm run dev

打开浏览器即可看的内容

Laravel

问题集合

别名@未定义

$ npm run dev

报错如下:

ERROR in ./resources/backend/router/index.js
Module not found: Error: Can't resolve '@/views/zip/index' in '/path/to/laravel-vue-admin/resources/backend/router'
 @ ./resources/backend/router/index.js 365:13-40
 @ ./resources/backend/main.js
 @ multi ./resources/backend/main.js

解决方法:在 webpack.mix.js 添加如下代码:

mix.webpackConfig({
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'resources/backend'),
    },
  },
})

卡在 70% 无法继续

> @ dev /path/to/laravel-vue-admin
> npm run development

> @ development /path/to/laravel-vue-admin
> cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js

 70% building 2069/2069 modules 0 active 

经过查找,找到文档,解决方法如下:

  1. 安装依赖
    $ npm install babel-plugin-dynamic-import-node --save-dev
  2. 修改 webpack.mix.js

具体如下:

mix.webpackConfig({
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'resources/backend'),
    }
  }
})
// 此处新增
.babelConfig({
  plugins: ['dynamic-import-node']
});

sass 中 /deep/ 解析失败

ERROR in ./resources/backend/components/HeaderSearch/index.vue?vue&type=style&index=0&id=6eba4ace&lang=scss&scoped=true& (./node_modules/css-loader!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/src??ref--7-2!./node_modules/sass-loader/lib/loader.js??ref--7-3!./node_modules/vue-loader/lib??vue-loader-options!./resources/backend/components/HeaderSearch/index.vue?vue&type=style&index=0&id=6eba4ace&lang=scss&scoped=true&)
Module build failed (from ./node_modules/sass-loader/lib/loader.js):

    /deep/ .el-input__inner {
   ^
      Expected selector.
    ╷
172 │     /deep/ .el-input__inner{
    │     ^
    ╵
  stdin 172:5  root stylesheet

这里应该是版本兼容问题。需要将所有 backend 目录中出现的 /deep/ 替换为 >>>

mock 资源无法加载

ERROR in ./resources/backend/main.js
Module not found: Error: Can't resolve '../mock' in '/path/to/laravel-vue-admin/resources/backend'
 @ ./resources/backend/main.js 31:0-34
 @ multi ./resources/backend/main.js

这个解决方案看你需要,如果你需要mock接口,那么需要复制原 vue-element-admin 中的 mock 文件夹到 resources/mock 即可。

如果不需要,则需要将依赖 mock 资源的代码删掉。
涉及 resources/backendmain.js

bable 失败

ERROR in ./resources/backend/layout/components/Sidebar/Item.vue?vue&type=script&lang=js& (./node_modules/babel-loader/lib??ref--4-0!./node_modules/vue-loader/lib??vue-loader-options!./resources/backend/layout/components/Sidebar/Item.vue?vue&type=script&lang=js&)
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: /path/to/laravel-vue-admin/resources/backend/layout/components/Sidebar/Item.vue: Unexpected token (20:18)

  18 | 
  19 |     if (icon) {
> 20 |       vnodes.push(<svg-icon icon-class={icon}/>)
     |                   ^
  21 |     }

经查询为 bable 没有正确配置,直接复制 vue-element-admin 中 babel.config.js 即可。

图标不显示

找了许久,没有一个方法可以完美解决。后来根据文章找到思路

  • 覆盖原始图片加载规则
  • 新增svg图片的加载

Mix.listen('configReady', (webpackConfig) => {
  // Exclude 'svg' folder from font loader
  let fontLoaderConfig = webpackConfig.module.rules.find(rule => String(rule.test) === String(/(\.(png|jpe?g|gif|webp)$|^((?!font).)*\.svg$)/));
  fontLoaderConfig.exclude = /(resources\/backend\/icons)/;
});

mix.webpackConfig({
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'resources/backend'),
    }
  },
  module: {
    rules: [
      {
        test: /\.svg$/,
        loader: 'svg-sprite-loader',
        include: [path.resolve(__dirname, 'resources/backend/icons/svg')],
        options: {
          symbolId: 'icon-[name]'
        }
      }
    ],
  }
}).babelConfig({
  plugins: ['dynamic-import-node']
});

然后完美执行:

 DONE  Compiled successfully in 19433ms                                                                                                                                                                                   10:33:44 AM
                                                                                                                                                                                                                                                                                       Asset      Size    Chunks             Chunk Names
                                                                               /css/app.css   174 KiB   /js/app  [emitted]  /js/app
                                                                                 /js/app.js  1.38 MiB   /js/app  [emitted]  /js/app
                                                                                /js/main.js  14.8 MiB  /js/main  [emitted]  /js/main
                                   fonts/element-icons.ttf?27c72091ab590fb5d1c3ef90f988ddce  10.8 KiB            [emitted]  
                                  fonts/element-icons.woff?9b70ee41d12a1cf127400d23534f7efc  5.98 KiB            [emitted]  
 fonts/vendor/element-ui/lib/theme-chalk/element-icons.ttf?6f0a76321d30f3c8120915e57f7bd77e  10.8 KiB            [emitted]  
fonts/vendor/element-ui/lib/theme-chalk/element-icons.woff?2fad952a20fbbcfd1bf2ebb210dccf7a  6.02 KiB            [emitted]  
                                            images/401.gif?089007e721e1f22809c0313b670a36f1   160 KiB            [emitted]  
                                            images/404.png?a57b6f31fa77c50f14d756711dea4158  95.8 KiB            [emitted]  
                                      images/404_cloud.png?0f4bc32b0f52f7cfb7d19305a6517724  4.65 KiB            [emitted]  
           images/vendor/tui-editor/dist/tui-editor-2x.png?b4361244b610df3a6c728a26a49f782b  23.9 KiB            [emitted]  
              images/vendor/tui-editor/dist/tui-editor.png?30dd0f529e5155cab8a1aefa4716de7f  10.6 KiB            [emitted]  

简单优化

  • 分开打包
mix.js('resources/backend/main.js', 'public/js').extract(['vue', 'axios']);
  • 添加随机参数,保障文件更新
if (mix.inProduction()) {
  mix.version();
}

最终 admin.blade.php

<!doctype html>
<html lang="{{ app()->getLocale() }}">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <title>title</title>
</head>
<body>
<div id="app"></div>
<script src="{{ mix('/js/manifest.js') }}"></script>
<script src="{{ mix('/js/vendor.js') }}"></script>
<script src="{{ mix('/js/main.js') }}"></script>
</body>
</html>

最终 webpack.mix.js

const mix = require('laravel-mix');

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */

Mix.listen('configReady', (webpackConfig) => {
  // Exclude 'svg' folder from font loader
  let fontLoaderConfig = webpackConfig.module.rules.find(rule => String(rule.test) === String(/(\.(png|jpe?g|gif|webp)$|^((?!font).)*\.svg$)/));
  fontLoaderConfig.exclude = /(resources\/backend\/icons)/;
});

mix.webpackConfig({
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'resources/backend'),
    }
  },
  module: {
    rules: [
      {
        test: /\.svg$/,
        loader: 'svg-sprite-loader',
        include: [path.resolve(__dirname, 'resources/backend/icons/svg')],
        options: {
          symbolId: 'icon-[name]'
        }
      }
    ],
  }
}).babelConfig({
  plugins: ['dynamic-import-node']
});

mix.js('resources/js/app.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css');

mix.js('resources/backend/main.js', 'public/js').extract(['vue', 'axios']);

if (mix.inProduction()) {
  mix.version();
}

总结

一定要多查看文档,在文档不能满足的情况下,多进行检索查询。尤其是图标无法显示这个问题,我在QQ群、Gitter上也有过咨询,没人回复。

还有,就是多多尝试。像图标这个问题,我也是多次打印 webpacke config 输出与原框架包中的输出做比较。

附上仓库地址 https://github.com/Honvid/laravel-vue-elem...

just do it.

本作品采用《CC 协议》,转载必须注明作者和本文链接
Honvid
本帖由系统于 4年前 自动加精
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 26

消灭0回复,已经star。谢谢分享!

4年前 评论
sreio

已收藏。谢谢分享

4年前 评论

老哥,你这个依赖有点多,laravel-mix 4 本身就依赖了babel 7 以上,看能不能精简下。

4年前 评论

话说都已经前后端分离了,为什么还要整合进一个项目里面呢

4年前 评论
ibucoin

可以考虑把后台独立出来,这样laravel只需要专注写api就可以了。

4年前 评论

@kylesean 嗯,这个可以有,我研究下。

4年前 评论

@Lex_Luth0r 纯个人项目,这样部署的时候不是那么麻烦。另外也可以顺道看看具体是咋用 laravel-mix 的。

4年前 评论

@ibucoin 是的,也可以这样做。 :smile:

4年前 评论

我都是做到的前后端分离,部署的时候,用nginx 转发请求,就一行,贼简单。
laravel-mix毕竟不如vue-cli,还是前后端分离的开发舒服,webpack-dev-server的 hmr 用起来最爽

4年前 评论
Hachiko 4年前
fhefh 4年前

我也推荐分成2个项目,laravel只做好API就行了

4年前 评论

laravel 专注做API, vue-element-admin 做界面展示和逻辑交互更合理,问题也比较少

4年前 评论

请问 /deep/ 改成>>> 之后是不报错了,但是也没有效果了怎么解决

4年前 评论

@Xqd93 额,我还没有全部对完样式。我找时间看下吧。看他们库的issue好像也说这么解决。

4年前 评论

tuandm/laravue,跟这个项目一样

4年前 评论

您好,从您的github上拉下来的代码,打开也不显示svg图标,找不到是哪里的问题了,

4年前 评论

@clown_shuo 有步骤,或者报错信息吗?

4年前 评论

我枯了,解决了一系列问题之后 在编译完的时候卡在

95% emitting unnamed compat plugin

还是乖乖的前后端分离吧 :sob:

4年前 评论

楼主我的图标还是不显示,没有任何报错只是图标不显示

4年前 评论

大佬,刚好也是我需要的。主要是passport管理客户端只能在本项目。

4年前 评论

图表不显示,没有任何报错

3年前 评论

@Honvid
file
登录后出现404怎么解决?

Laravel

main.js的mock处理已经删除。

3年前 评论
Honvid (楼主) 3年前
Haven

厉害了,非常详细

3年前 评论

感谢您的分享,在laravel5.8的环境中已成成功集成了vue-element-admin3。但是在laravel7中集成vue-element-admin4的时候,出现了好多这里没有的问题,能否再分享一下laravel7+vue-element-admin4呢。谢谢。

3年前 评论

不知道楼主,有没有遇到 frontend backend 冲突了? 我现在都是放在一起的,各个UI 冲突了,没找到原因。backend 也就是vue-element-admin 页面 403 Forbidden。

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!