vue-cli 4.x.x搭建项目及配置

安装cli

若之前安装过2.x.x,3.x.x建议卸载

npm uninstall vue-cli -g 
# or
yarn global remove vue-cli

可以通过npm list --global --depth=0,查看当前全局安装的包(–depth 表示深度,我们使用的模块会有依赖,深度为零的时候,不会显示依赖模块),也可直接npm list <packagename>

npm install -g @vue/cli
# OR
yarn global add @vue/cli

查看是否安装成功``

# 输入
$ npm list --global @vue/cli
# 输出
/Users/linqiang/.nvm/versions/node/v10.18.0/lib
└── @vue/cli@4.1.1

创建项目

vue create [project-name]

配置pug

npm i pug pug-plain-loader pug-loader pug-filters -D

配置全局sass变量

// vue.config.js
module.exports = {
    css: {
        loaderOptions: {
            // 给 sass-loader 传递选项
            sass: {
                // @/ 是 src/ 的别名
                // 所以这里假设你有 `src/variables.sass` 这个文件
                // 注意:在 sass-loader v7 中,这个选项名是 "data"
                prependData: `@import "~@/assets/css/_global-variables.sass";`
            }
        }
    }
};

Node Sass to Dart Sass

sass官方已经将dart-sass作为未来主要的的开发方向了,有任何新功能它都是会优先支持,dart-sass之所以容易安装,主要是因为它会被编译成纯 js,这样就可以直接在的 node 环境中使用。虽然这样它的运行速度会比基于libsass的慢一些些,但这些速度的差异几乎可以忽略不计。目前vue-cli在选择sass预处理的时候也会默认优先使用dart-scss

升级也非常的简单,只需要两个步骤

# 先卸载
npm uninstall node-sass 
# 再安装
npm install sass -S -D
# 我的版本"sass": "^1.32.2","sass-loader": "^8.0.2"

更新vue.config.js

// vue.config.js
module.exports = {
  css: {
    loaderOptions: {
      sass: {
        implementation: require('sass'), // This line must in sass option
      },
    },
  }
}

替换 node-sass 之后有一个地方需要注意,就是它不再支持之前 sass 的那种 /deep/ 写法,需要统一改为 ::v-deep 的写法。

.a {
  /deep/ {
    .b {
      color: red;
    }
  }
}

/* 修改为 */
.a {
  ::v-deep {
    .b {
      color: red;
    }
  }
}

这里在配置的时候报了了个错:

Syntax Error: SassError: semicolons aren't allowed in the indented syntax.

是在vue.config.js中配置全局sass变量时有问题

// 原配置
            
            sass: {
                implementation: require('sass'), // use dart-sass, This line must in sass option
                // @/ 是 src/ 的别名
                // 所以这里假设你有 `src/variables.sass` 这个文件
                // 注意:在 sass-loader v7 中,这个选项名是 "data"
                prependData: `$baseUrl: "${baseUrl}";@import "~@/assets/css/_global-variables.sass"`
            },
// 改为
           
            sass: {
                implementation: require('sass'), // use dart-sass, This line must in sass option
                // @/ 是 src/ 的别名
                // 所以这里假设你有 `src/variables.sass` 这个文件
                // 注意:在 sass-loader v7 中,这个选项名是 "data"
                prependData: `
                    $baseUrl: "${baseUrl}"
                    @import "~@/assets/css/_global-variables.sass"
                `
            },

使用dart-sass后element-ui按需引入打包字体出错

详见:https://github.com/PanJiaChen/vue-element-admin/issues/3526、https://github.com/ElemeFE/element/issues/19247

原因:dart-sass编译时会将对应的unicode编码转换成对应unicode明文,所以通过伪元素来展示的图标如el-icon-arrow:before{ content: "\e6df"},编译之后就变成了el-icon-arrow:before{ content: ""},“”便是一个双字节字符

解决方案:

将自定义主题引入入口文件
scss @import "~element-ui/packages/theme-chalk/src/index.scss";
中的内容解开引用,这里不去写具体内容,指的注意的是以下:
注意将第一个
@import "./base.scss";
再次解开为:
sass @import "./common/transition.scss";
也就是将 内部的./icon.scss 排除掉
然后将elementui编译好的icon.css单独用js进行引入加载,即可解决

babel.config.js配置:

module.exports = {
    plugins: [
        [
            'component',
            {
                libraryName: 'element-ui',
                style: false // 默认不加载样式,使用项目自定义主题加载样式
            }
        ]
    ]
}

背景图路径处理方案

处理静态资源

在实际开发中会遇到本地开发环境的同线上背景图片资源地址不同的情况,这里我遇到的是在本地开发中的路径是/images/a.png,线上的地址是/xxx/images/a.png,其中xxx是部署应用包时的基本 URL对应vue.config.js 中的 publicPath 选项,针对以下两种情况:

  1. 直接书写的css样式中的背景图路径
  2. 具体业务中通过js动态设置背景图路径

考虑解决方案:

  1. 将图片统一放在publilc/images下
  2. 解决直接书写的样式中的背景图路径: 在vue.config.js中注入sass全局变量$baseUrl,其值等于publicPath
  3. 解决js动态设置背景图路径:挂载Vue.prototype.$baseUrl = process.env.BASE_URL, BASE_URL - 会和 vue.config.js 中的 publicPath 选项相符,即你的应用会部署到的基础路径(详情)。
// vue.config.js

const baseUrl = process.env.NODE_ENV === 'production' ? '/sub/' : '/';

module.exports = {
  publicPath: baseUrl,
  css: {
    loaderOptions: {
      sass: {
        data: `$baseUrl: "${baseUrl}";`
      }
    }
  }
}
// main.js
Vue.prototype.$baseUrl = process.env.BASE_URL;

在sass中使用

background-image: url($baseUrl + 'images/logo.png')

在js中使用

let dom = document.createElement('div');
dom.innerHTML = `<div style="background-image: url(${vm.$baseUrl}/images/logo.png)">`;

移动端适配-rem方案

postcss-pxtorem

// vue.config.js
const autoprefixer = require('autoprefixer');
const pxtorem = require('postcss-pxtorem');

module.exports = {
    css: {
        loaderOptions: {
            postcss: {
                plugins: [
                    autoprefixer(),
                    pxtorem({
                        rootValue: 50, // 根节点的
                        propList: ['*']
                    })
                ]
            }
        }
    }
};

移动端适配-viewport方案

postcss-px-to-viewport

// vue.config.js
const autoprefixer = require('autoprefixer');
const pxtoviewport = require('postcss-px-to-viewport');
module.exports = {
    css: {
        loaderOptions: {
            postcss: {
                plugins: [
                    autoprefixer(),
                    pxtoviewport({
                        // 视窗的宽度,对应设计稿的宽度
                        viewportWidth: 375,
                        // 视窗的高度,根据750设备的宽度来指定,一般指定1334,也可以不配置
                        // viewportHeight: 1334,
                        // 指定`px`转换为视窗单位值的小数位数
                        unitPrecision: 3,
                        // 指定需要转换成的视窗单位,建议使用vw
                        viewportUnit: 'vw',
                        // 指定不转换为视窗单位的类,可以自定义,可以无限添加,建议定义一至两个通用的类名
                        selectorBlackList: ['.ignore'],
                        // 小于或等于`1px`不转换为视窗单位,你也可以设置为你想要的值
                        minPixelValue: 1,
                        // 允许在媒体查询中转换`px`
                        mediaQuery: false
                    })
                ]
            }
        }
    }
};

移动端调试

vConsole

// main.js
// 仅在开发环境下面使用vConsole进行调试
if (process.env.NODE_ENV === 'development') {
  const VConsole = require('vconsole')
  new VConsole()
}

配置element-ui

按需引入需要安装plugin

npm install babel-plugin-component @babel/preset-env -D

配置引入

// main.js
import 'element-ui/lib/theme-chalk/index.css';
import { Button, Select } from 'element-ui';
Vue.use(Button);
Vue.use(Select);

// babel.config.js
module.exports = {
    presets: [
        '@vue/cli-plugin-babel/preset',
        ['@babel/preset-env', { 'modules': false }]
    ],
    'plugins': [
        [
            'component',
            {
                'libraryName': 'element-ui',
                'styleLibraryName': 'theme-chalk'
            }
        ]
    ]
};

自定一主题报错

element-variables.scss)
Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: media query expression must begin with '('
        on line 2 of /Users/linqiang/Documents/workplace/vte-management-platform/src/element-ui-config/element-variables.scss

额,上方引入的全局的sass变量需要加;

...
prependData: `@import "~@/assets/css/_global-variables.sass";`
...

配置history模式

NGINX配置

# 根域名下或使用docker部署时
location / {
   # try_files $uri $uri/ =404;
   try_files $uri $uri/ /index.html;
}
# 如果是多级目录则
location /patient/ {
   try_files $uri $uri/ /patient/index.html;
}
location /patient/smart/ {
    expires 0;
    alias /home/work/dev/web/smart/dist/;
    try_files $uri $uri/ /patient/smart/index.html;		
}
# location /monitor/ {
#     expires 0;
#     alias /home/work/dev/web/monitor/dist/;
#     try_files $uri $uri/ =404;
# }
# location ~ ^/api/(.*)$ {
#     proxy_pass http://cnblogs.com/api/$1;
# }

修改后重启NGINX

# chown -R linqiang.fan /home/work/dev/web
# sudo su - root
nginx -s reload

### 查询执行历史
history|grep nginx
### 验证一下配置的是否正确
sudo /home/work/nginx/sbin/nginx -t 
### 如果没有找到nginx命令
sudo /home/work/nginx/sbin/nginx -s reload

router配置

...
export default new Router({
    mode: 'history',
    // base: 'subsite', // 如果有二级路由则需要配置base为二级路由的名称
    routes: routers
});

本地调试

module.exports = {
    ... ...
    publicPath: './',
    devServer: {
        // https://github.com/bripkens/connect-history-api-fallback#rewrites
        historyApiFallback: { // history模式的路由回退配置
            // verbose: true, // 打印日志
            rewrites: [
                {
                    from: /(.*)\/(css|js|data|fonts|images|img)\/(.*)/,
                    to(context) {
                        return context.parsedUrl.pathname.replace(/(.*)\/(css|js|data|fonts|images|img)\/(.*)/, '/$2/$3');
                    }
                }
            ]
        }
    }
    ... ...
};

配置调试预置cookie

    devServer: {
        proxy: {
            '/api': {
                // target: 'xxxx',
                target: 'http://xxx.com',
                changeOrigin: true,
                pathRewrite: {
                    
                },
                onProxyReq: function(proxyReq, req, res) {
                    proxyReq.setHeader('cookie', 'SESSION=' + 'xxxx' );
                }
            }
        }
    }

配置optional-chaining

安装插件

@babel/plugin-proposal-optional-chaining

在babel.config.js中配置

module.exports = {
    'plugins': [
        '@babel/plugin-proposal-optional-chaining'
    ]
};

若eslint报错则添加配置到.eslintrc.js

module.exports = {
    parserOptions: {
        parser: 'babel-eslint'
    }
}

配置stylelint

https://juejin.cn/post/6844903753263366157

eslint 配置全局变量无需校验

module.exports = {
    globals: {
        google: true // 例如:google map 全局变量
    },
}

添加gitHooks:pre-commit

安装包

npm i lint-staged -D

在package.json中添加:

{
...
    "gitHooks": {
        "pre-commit": "lint-staged"
    },
    "lint-staged": {
        "src/**/*.{js,vue}": [
            "eslint --fix",
            "git add"
        ]
    }
}

报错

Missing class properties transform:

1.
npm i babel-plugin-transform-class-properties --save-dev
2.
.babe.rc中添加插件
"plugins":["transform-class-properties"]

sass 与 js 共享变量

详见https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass

// styles/animation.scss
$animation-length: 250;
$animation-length-ms: $animation-length + 0ms;

:export {
  animationMillis: $animation-length-ms;
}

.component-enter {
  ...

  transition: all $animation-length-ms ease-in;
}
import styles from '../styles/animation.scss'
// 需要注意的是,返回的值都是字符串类型
const millis = parseInt(styles.animationMillis)

!> 测试了下,.sass文件貌似不支持

prod环境去掉console.log

vue.config.js 中添加

configureWebpack: config => {
    if (process.env.NODE_ENV === 'production') {
       config.optimization.minimizer[0].options.terserOptions.compress.drop_console = true;
    }
}

兼容ie 11

  1. 首先按官方浏览器兼容配置:https://cli.vuejs.org/zh/guide/browser-compatibility.html#browserslist
  2. 有一些包需要重新通过babel编译(使用正则的原因大概是因为使用的是cnpm安装的包,使用npm安装的可以直接使用包名)

参考:
https://www.jianshu.com/p/5ab8495e0d0f
https://blog.csdn.net/tyy9868/article/details/91905171

transpileDependencies: [
        /[/\\]node_modules[/\\](.+?)?element-ui(.*)[/\\]src/,
        /[/\\]node_modules[/\\](.+?)?element-ui(.*)[/\\]package/,
        /[/\\]node_modules[/\\](.+?)?vue-router/,
        /[/\\]node_modules[/\\](.+?)?@yiducloud(.*)[/\\].*/,
        /[/\\]node_modules[/\\](.+?)?sparklines/,
    ],
posted @ 2019-12-20 17:42  fanlinqiang  阅读(4651)  评论(0)    收藏  举报