前端日常经验积累

后续更新,将迁移到github

文章记录项目开发中遇到或者看到的一些难点,方便日后查找
持续更新

构建工具相关

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相关

  1. 安装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",否则浏览器不会渲染

posted @ 2016-11-18 00:01  chenEdgar  阅读(686)  评论(0编辑  收藏  举报