在项目采用vue.js做前端框架时,我在配置生产环境以及将项目部署到服务器时遇到了不少问题,在这里简单记录下解决问题的方法和学到的知识。
理解npm run dev 和 npm run build命令
在构建vue项目时,通常是下载安装node.js,利用node.js自带的npm模块安装vue-cli脚手架,然后通过vue-cli来构建项目。通过这样构建完成项目后,在开发环境中,我们只需要在项目根目录打开cmd,然后执行npm run dev命令,就可以访问localhost:8080看到前端页面效果。后期在发布环境中使用npm run build打包项目再放到发布服务器中。
实际上这两个命令都是npm run script脚本命令,后面接的脚本名其配置在项目根目录的"package.json"文件中。 想详细了解npm脚本可以看阮大神的这篇package.json文件"scripts": { "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", "start": "npm run dev", "unit": "jest --config test/unit/jest.conf.js --coverage", "test": "npm run unit", "build": "node build/build.js" },
npm run dev 执行的实际上是build/webpack.dev.conf.js文件,该文件会在本地创建一个express服务器提供静态文件服务,可以在devServer属性中指定配置信息。例如如果需要使用后台api的话,考虑到服务器跨域问题,需要配置proxyTable,作请求代理。
webpack.dev.conf.js文件devServer: { clientLogLevel: 'warning', historyApiFallback: { rewrites: [ { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, ], }, hot: true, contentBase: false, // since we use CopyWebpackPlugin. compress: true, host: HOST || config.dev.host, port: PORT || config.dev.port, open: config.dev.autoOpenBrowser, overlay: config.dev.errorOverlay ? { warnings: false, errors: true } : false, publicPath: config.dev.assetsPublicPath, proxy: config.dev.proxyTable, quiet: true, // necessary for FriendlyErrorsPlugin watchOptions: { poll: config.dev.poll, } }
类似的,npm run build命令运行的是build/build.js脚本。
两个脚本的主要配置信息,一般都是在config/index.js中配置,dev对象配置开发环境,build对象配置发布环境config/build.js文件dev: { // Paths assetsSubDirectory: 'static', assetsPublicPath: '/', proxyTable: { '/api':{ target:'http://127.0.0.1:8080/xxx', changeOrigin:true, } }, ...... },build: { // Template for index.html index: path.resolve(__dirname, '../dist/index.html'), // Paths assetsRoot: path.resolve(__dirname, '../dist'), assetsSubDirectory: 'static', assetsPublicPath: './', ...... }
开发环境的服务器跨域问题
使用npm run dev会在本地建立一个express服务器,这样使得开发时前端页面可以实现实时热加载。但是由于浏览器同源策略,当我们需要请求另一个后台服务器的接口数据时会遇到服务器跨域的问题。在这里,我们可以通过webpack配置vue的proxyTable解决跨域。
首先在config/index.js中的dev对象配置proxyTableindex.js 文件dev: { // Paths assetsSubDirectory: 'static', assetsPublicPath: '/', proxyTable: { '/api':{ target:'http://127.0.0.1:8080/xxx', //代理服务器ip+port+项目名,或者直接填写域名 changeOrigin:true, //是否跨域 pathRewrite: { '^/api': '/api' //需要rewrite重写的,这种接口配置出来 http://127.0.0.1:8080/xxx/api/login // '^/api': '' 这种接口配置出来 http://127.0.0.1:8080/xxx/login } } }, ...... },
配置开发环境和生产环境的接口地址
项目发布到服务器时,开发环境配置的代理接口是无效的。为了方便开发部署,可以通过配置根据不同环境改变接口地址。
开发环境的接口可以配置在config/dev.env.js中
config/dev.env.js文件'use strict'const merge = require('webpack-merge')const prodEnv = require('./prod.env')module.exports = merge(prodEnv, { NODE_ENV: '"development"', API_HOST:'"/api/"' //增加一个API_HOST属性,配置好开发环境的接口地址})
发布环境的接口地址可以配置在prod.env.js中
config/prod.env.js文件'use strict'module.exports = { NODE_ENV: '"production"', API_HOST:'"//127.0.0.1:8080/sfc-platform/api/"' //同样增加一个API_HOST属性,配置好开发环境的接口地址}
这里主要利用了node.js中的process对象,它是一个进程相关的全局对象,process.env会返回用户运行环境对象。通过这种配置,当我们在js中请求接口数据时可以直接使用process.env.API_HOST拼接url来请求数据。
this.$http.post(process.env.API_HOST+"register",data).then(function(res){ })
将vue打包发布到服务器
npm run build命令会在项目根目录生成一个dist文件夹,里面包含一个static文件夹和一个index.html的文件。我们可以直接放在apache,tomcat,nginx等服务器上。如果项目不是放在服务器的根目录,例如java项目可以放在项目目录下,跟WEB-INF同级,可能会有资源丢失的问题出现,遇到这种问题,我们可以在config/index.js中修改配置。
build: { // Template for index.html index: path.resolve(__dirname, '../dist/index.html'), // Paths assetsRoot: path.resolve(__dirname, '../dist'), assetsSubDirectory: 'static', assetsPublicPath: './', //原来这个值是"'/'",修改成"'./'"即可 ...... }
当然,如果你还用到了vue-router,需要通过配置将所有的url都转发到index.html页面避免一些404错误。