文章记录项目开发中遇到或者看到的一些难点,方便日后查找
持续更新
构建工具相关
1.gulp 中配置全局环境变量
为了配置debug 和 .min 两份js文件,需要根据命令输入,将文件输出不用的版本
解决方案: 通过commander,获取命令行输入的参数,更具参数判断是什么环境,代码如下:
var gulp = require('gulp'),
stripDebug = require('gulp-strip-debug'),//清楚调试用console, alert
cssmini = require('gulp-minify-css'),
uglify = require('gulp-uglify'),
program = require('commander'); // 获取命令行参数
program
// .option('-b, --build', 'production') // 配置命令行参数
// .option('-d, --development', 'development')
.option('build, --build', 'build')
.parse(process.argv)
console.log(program)
var ENV = program.build ? 'build' : 'production';
// 配置gulp task
if (ENV === 'build') { // 生产版
gulp.task('build', function () {
// your code
})
} else {
gulp.task('dev', function () { // 开发版
// your code
})
}
命令行输入 gulp build,就能看到输出的program对象了,根据build参数,执行打包build生产版本
2.gulp less中如何引入.css 文件
// 直接在less中通过
import "a.css" // Error: Broken @import declaration of "../../iconfont/iconfont.css"
有三种方法:
1中时直接将.css 改为 .less;
2是通过修改导入规则 @import (inline) "../../iconfont/iconfont.css";
3直接在index.html通过link导入
方法1,iconfont的font-family语法 less不支持
方法2,简单又粗暴
方法3,有一个坑: 通过import道路的css文件如果里面还有import导入,比如iconfont.css中,通过相对路径导入了字体文件,
导致打包后的min.css 中字体引用路径出错,字体路径将是相对于min.css。 解决方法通过gulp新设置一个task, 每次执行build时
将iconfont/下的字体文件复制到iconfont.css 中字体引用的相对路径文件下。
注:群里 杭州-LCY则认为不要通过import导入静态资源(资源里面又包含import的情况)
最终解决方案是:选择2,直接link 引用
3 webpack配置文件
不同环境,build生成的index.html引入的静态资源路径不同
比如:
测试环境 为index-test.html, 静态资源引用为 test-static.css
预发布环境 为index-staging.html, 静态资源引用为 staging-static.css
线上环境 为index.html, 静态资源引用为 static.css
之前的做法是打包到测试,预发布,和线上时都需要手动更新配置文件资源引用的路径,出错是难免的。避免不必要的出错的有效方法是:将这些重复的工作自动化。
使用vue-cli构建项目,当我们执行npm run build
打包发布的时候,它的工作过程是怎样的呢。
1:命令行输入npm run build
2: 读取package.json中的script下的build,node 执行 build.js
"scripts": {
"dev": "node build/dev-server.js",
"build": "node build/build.js", // npm run build
"buildstaging": "node build/build-staging.js", // 新增预发布环境打包 npm run buildstaging
"buildtest": "node build/build-test.js", // 新增test环境打包 npm run buildtest
"unit": "karma start test/unit/karma.conf.js --single-run",
"e2e": "node test/e2e/runner.js",
"test": "npm run unit && npm run e2e",
"lint": "eslint --ext .js,.vue src test/unit/specs test/e2e/specs"
},
3: 更具build.js 编写的程序执行代码压缩等功能。
顺着这个思路查看 build.js 代码,先附上配置文件结构图:
使用vue-cli构建项目代码,如下
build.js代码如下
// https://github.com/shelljs/shelljs
require('shelljs/global')
env.NODE_ENV = 'production' // 却别在这里,将production改为对应文件的环境变量
var path = require('path')
var config = require('../config')
var ora = require('ora')
var webpack = require('webpack')
var webpackConfig = require('./webpack.prod.conf')
console.log(
' Tip:\n' +
' Built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'
)
var spinner = ora('building for staging production...')
spinner.start()
var assetsPath = path.join(config.build.assetsRoot, config.build.assetsSubDirectory) // dist/static
rm('-rf', assetsPath)
mkdir('-p', assetsPath)
cp('-R', 'static/', assetsPath)
webpack(webpackConfig, function (err, stats) {
spinner.stop()
if (err) throw err
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}) + '\n')
})
红色方框中的文件是新增或则修改过的。build-staging和build-test.js与 build.js的却别在于 env.NODE_ENV = 'production'
设置的环境变量不同。
npm相关
- 安装node-sass模块报错
- Error: Cannot find module 'generate-object-property'
删除node_modules, 重新安装解决
CSS相关
静态定位position: static 元素通过translate改变位置后,原字体将会保留在原位置
在线demo:
解决方法是将元素设置为绝对定位position: absolute
跨域相关
动态创建script,属于异步加载,执行先后顺序问题
假设a.js和b.js 只在微信环境才引入,且b.js 依赖于a.js
if (navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger') { // 微信
var script1 = document.createElement('script');
var script2 = document.createElement('script');
script1.src= 'a.js'
script2.src= 'b.js'
document.getElementsByTagName('head')[0].appendChild(script1)
//其他通过load属性
//ie只能通过script的readystatechange属性
// 判断script的加载完成
script1.onload=script1.onreadystatechange=function(){
if(!this.readyState||this.readyState=='loaded'||this.readyState=='complete'){
document.getElementsByTagName('head')[0].appendChild(script2)
}
script1.onload=script1.onreadystatechange=null;
}
}
如果b.js是不是立即执行函数,只要script的插入顺序正确,两个js的执行不会有什么问题;
若果b.js是立即执行函数且依赖于a.js,那么像上面这样,等到a.js加载完毕在执行加载b.js就有必要了。
动态创建的script如果需要写入js,使用script.text = 'your code', 不使用innerHTML
动态插入link引入cdn的资源也需要设置跨域头,不然会产生跨域问题。动态创建的link标签引入样式,记得需要rel="stylesheet",否则浏览器不会渲染