由于 css 中的 svg,无法使用 vue cli 3 模板构建项目

Posted

技术标签:

【中文标题】由于 css 中的 svg,无法使用 vue cli 3 模板构建项目【英文标题】:Could not build project with vue cli 3 template due to svg in css 【发布时间】:2019-01-30 10:41:15 【问题描述】:

在迁移到 vue-cli 3 时,我遇到了以下问题。 我将插件的 css 导入我的 app.scss。

这一行:background-image: url(default-skin.svg); 中断 yarn build,会引发此错误:

Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ReferenceError: navigator is not defined

这是我的 vue.config.js:

const path = require('path')
const webpack = require('webpack')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const SpriteLoaderPlugin = require('svg-sprite-loader/plugin')

const ASSETS_DIR = 'static'

module.exports = 
  assetsDir: ASSETS_DIR,
  runtimeCompiler: true,
  chainWebpack: config => 
    config
      .plugin('provide-plugin')
        .use(webpack.ProvidePlugin, [
          axios: "axios",
          $: "jquery",
          jQuery: "jquery",
          _: "lodash",
          mapGetters: ['vuex', 'mapGetters'],
          mapActions: ['vuex', 'mapActions']
        ])
        .end()
      .plugin('copy-plugin')
        .use(CopyWebpackPlugin, [
          [
            from: path.resolve(__dirname, 'static'),
            to: ASSETS_DIR,
            ignore: ['.*']
          ]
        ])
        .end()
      .plugin('sprite-loader-plugin')
        .use(SpriteLoaderPlugin)

    config.module
      .rule('svg')
        .test(/\.svg$/)
        .use('file-loader')
          .loader('svg-sprite-loader')
  

有什么办法吗?

更新

The css which breaks yarn build

包.json:


  "name": "f2c",
  "version": "1.0.0",
  "description": "A Vue.js project",
  "author": "Victor Ponamariov <victor.ponamariov@gmail.com>",
  "private": true,
  "scripts": 
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  ,
  "dependencies": 
    "animate.css": "^3.6.1",
    "axios": "^0.18.0",
    "blueimp-canvas-to-blob": "^3.14.0",
    "fabric": "^2.3.3",
    "flexboxgrid": "^6.3.1",
    "intl-tel-input": "^12.4.0",
    "jquery": "^3.3.1",
    "libphonenumber-js": "^1.2.21",
    "lodash": "^4.17.10",
    "masonry-layout": "^4.2.1",
    "moment": "^2.22.2",
    "nprogress": "^0.2.0",
    "perfect-scrollbar": "^1.4.0",
    "photoswipe": "^4.1.2",
    "portal-vue": "^1.3.0",
    "raven-js": "^3.25.2",
    "sharer.js": "^0.3.3",
    "stickyfilljs": "^2.0.5",
    "tippy.js": "^2.5.2",
    "vee-validate": "^2.0.6",
    "vue": "^2.5.2",
    "vue-analytics": "^5.14.0",
    "vue-carousel": "^0.9.0",
    "vue-clipboard2": "^0.1.1",
    "vue-cropperjs": "^2.2.0",
    "vue-gtm": "^1.0.2",
    "vue-i18n": "^8.0.0",
    "vue-infinite-loading": "^2.3.3",
    "vue-infinite-scroll": "^2.0.2",
    "vue-meta": "^1.5.2",
    "vue-mq": "^0.2.1",
    "vue-multiselect": "^2.1.0",
    "vue-perfect-scrollbar": "^0.1.0",
    "vue-popperjs": "^1.2.6",
    "vue-router": "^3.0.1",
    "vue-select": "^2.4.0",
    "vue-slider-component": "^2.7.4",
    "vue-social-sharing": "^2.3.3",
    "vue-star-rating": "^1.6.0",
    "vue-sweetalert2": "^1.5.2",
    "vue-tippy": "^2.0.18",
    "vue-yandex-metrika": "^1.6.1",
    "vuex": "^3.0.1"
  ,
  "devDependencies": 
    "@vue/cli-plugin-babel": "^3.0.0-rc.5",
    "@vue/cli-plugin-eslint": "^3.0.0-rc.5",
    "@vue/cli-service": "^3.0.0-rc.5",
    "copy-webpack-plugin": "^4.5.2",
    "node-sass": "^4.9.2",
    "normalize.css": "^8.0.0",
    "postcss-import": "^11.1.0",
    "postcss-url": "^7.3.2",
    "sass-loader": "^7.0.3",
    "svg-sprite-loader": "^3.8.0",
    "vue-template-compiler": "^2.5.16",
    "webpack-svgstore-plugin": "^4.0.3"
  ,
  "eslintConfig": 
    "root": true,
    "env": 
      "node": true
    ,
    "extends": [
      "plugin:vue/essential",
      "eslint:recommended"
    ],
    "globals": 
      "$": false,
      "jQuery": false,
      "_": false,
      "axios": false,
      "VK": false,
      "gapi": false,
      "FB": false,
      "mapGetters": false,
      "mapActions": false
    ,
    "rules": ,
    "parserOptions": 
      "parser": "babel-eslint"
    
  ,
  "postcss": 
    "plugins": 
      "autoprefixer": ,
      "postcss-import": ,
      "postcss-url": 
    
  ,
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not ie <= 8"
  ]

应用文件夹结构:

【问题讨论】:

您使用的是哪个版本的svg-sprite-loader?就此而言,您能否提供minimum, complete and verifiable example? 感谢您的回复!我正在使用最新(3.8.0)版本的 svg-sprite-loader。我不确定如何在 jsfiddle 上提供示例,因为它仅在构建项目时发生,它不是网页上的运行时错误。我所拥有的只是:带有我提供的配置的 vue cli 3 模板,以及我从外部插件中包含的一个 .css 文件,该插件在背景图像中有 .svg,这会破坏构建(即使 yarn serve 工作正常)。我很乐意提供更多信息! :) 您可以共享文件夹结构、css 文件的内容以及 package.json、JIC 的内容。 完成。什么是JIC? :) JIC = 以防万一 【参考方案1】:

尝试删除节点模块文件夹,然后再次运行 yarn install。

如果不成功,请尝试:

global.navigator = 
  userAgent: 'node.js'
;

【讨论】:

尽管有错误消息,但这与导航器对象无关。问题在于 svg loader 或类似的东西。另外,如果我重新定义 userAgent,那么我如何确定用户的真实 userAgent 是什么?【参考方案2】:

Ref vue-pswipe, GuoQichen 将此配置用于 svg。

config.module
  .rule('svg')
  .use('file-loader')
  .clear()
  .loader('url-loader')
  .options(
    limit: 4 * 1024,
    name: 'img/[name].[hash:8].[ext]',
  )

【讨论】:

【参考方案3】:

我没有修复或完整的解释,但有一个解决方法...

从 SFC 的 &lt;style&gt; 标记内导入 CSS 文件时,问题似乎是由 postcss-import 引起的:

// App.vue
<style lang="scss">
  @import 'app.scss'; /* imports default.css -> default-skin.svg */
</style>

您可以通过将导入移至&lt;script&gt; 标记(或main.js)来解决构建错误:

// App.vue
<script>
  import 'app.scss'; /* imports default.css -> default-skin.svg */
</script>

见GitHub repo

【讨论】:

以上是关于由于 css 中的 svg,无法使用 vue cli 3 模板构建项目的主要内容,如果未能解决你的问题,请参考以下文章

在 Vue 模板文件中的伪元素内容或背景图片中使用 SVG

Vue:使用 scoped 时 CSS 不适用于 D3 的 svg

svg图标无法修改颜色的解决方案

使用 css 更改颜色 svg 文件

如何在 Vue 的 css 部分中加载外部 svg

我无法使用 CSS 控制动画 svg 边框