❶ 白鹭发布ES6时uglify-js不支持es6的解决方案
试了一下发布ES6,结果报错,不支持uglify-js,需要换插件。从论坛中找到如下链接:
https://bbs.egret.com/forum.php? ... 52516&highlight=es6
但是看了一下发现并不是很合适,因为Egret中有不少地方用到了uglify-js,换起来有点麻烦。
这里我直接使用uglify-js的harmony分支uglify-es,源在github上:
https://github.com/mishoo/UglifyJS2/tree/harmony
按以下步骤操作:
1.按上面链接的文档进行安装,我直接npm安装的,没有替换Egret集成的uglify-js
2.安装完后找到Egret库中的utils.js,我的悄晌Mac目录在:/Users/xxxxxx/Library/Application Support/Egret/engine/5.2.14/tools/lib/utils.js
3.打开utils.js进行修改:
找到:
修改为:
完成第一步,此处使用刚安装好的库
然后找到:
修改为:
此处是为了处理egret publish的时候会引起的编译错误。
4.执行egret publis,可以正常发布。
目前我这么处理还没问题,不知道是否有隐藏问题,感谢指正。
ES6越来越广泛,期待Egret官方能够把常用集成库都处理成支持ES6的版本。
5.备注:
uglify在对第三方库生成.min.js时,如果想集成到Egret中,不要加参数,直接输出即可。示例如下:
1.错误写法,能正常debug能正常release但不能正常运行:
2.正确写法,全部散激正常:
** 补充:如果编译目标可为es5,忽略以上全部说明,直接在冲运袜lib中添加es6配置即可,如下
❷ React | 使用webpack构建React项目
配置 React 项目,需要完成的工作:
1、编译 jsx,es6,scss 等资源
2、裤闭自动引入静态资源到 html 页面
3、实时编译和刷新浏览器
4、按指定模块化规范自动包装模块
5、自动给 css 添加浏览器内核前缀
6、按需打包合并 js、css
根据 webpack 文档编写最基本的 webpack 配置,直接使用 node api 的方式
/* webpack.config.js */
var webpack= require( 'webpack' );
// 辅助函数 var utils= require( './utils' );
var fullPath=utils.fullPath;
var pickFiles=utils.pickFiles;
// 项磨大目根路径 var ROOT_PATH=fullPath( '../' );
// 项目源码路径胡游裂 var SRC_PATH=ROOT_PATH+ '/src' ;
// 产出路径 var DIST_PATH=ROOT_PATH+ '/dist' ;
// 是否是开发环境 var __DEV__= process.env. NODE_ENV !== 'proction' ;
// conf
var alias=pickFiles({
id :/(conf\/[^\/]+).js$/,
pattern :SRC_PATH+ '/conf/*.js'
});
// components
alias= Object.assign(alias,pickFiles({
id :/(components\/[^\/]+)/,
pattern :SRC_PATH+ '/components/*/index.js'
}));
// recers
alias= Object.assign(alias,pickFiles({
id :/(recers\/[^\/]+).js/,
pattern :SRC_PATH+ '/js/recers/*'
}));
// actions
alias= Object.assign(alias,pickFiles({
id :/(actions\/[^\/]+).js/,
pattern :SRC_PATH+ '/js/actions/*'
}));
var config= {
context :SRC_PATH,
entry : {
app : [ './pages/app.js' ]
},
output : {
path :DIST_PATH,
filename : 'js/bundle.js'
},
mole : {},
resolve : {
alias :alias
},
plugins : [
new webpack.DefinePlugin({
// http://stackoverflow.com/questions/30030031/passing-environment-dependent-variables-in-webpack
"process.env.NODE_ENV" : JSON .stringify(process.env. NODE_ENV || 'development' )
})
]
};
mole.
exports =config;
/* webpack.dev.js */
var webpack= require( 'webpack' );
var WebpackDevServer= require( 'webpack-dev-server' );
var config= require( './webpack.config' );
var utils= require( './utils' );
var PORT=8080;
var HOST=utils.getIP();
var args= process.argv;
var hot=args.indexOf( '--hot' ) > -1;
var deploy=args.indexOf( '--deploy' ) > -1;
// 本地环境静态资源路径 var localPublicPath= 'http://' +HOST+ ':' +PORT+ '/' ;
config.output. publicPath =localPublicPath;
config.entry.app.unshift( 'webpack-dev-server/client?' +localPublicPath);
new WebpackDevServer(webpack(config), {
hot :hot,
inline : true ,
compress : true ,
stats : {
chunks : false ,
children : false ,
colors : true
},
// Set this as true if you want to access dev server from arbitrary url.
// This is handy if you are using a html5 router.
historyApiFallback : true ,
}).listen(
PORT,HOST, function () {
console .log(localPublicPath);
});
编译 jsx、es6、scss 等资源:
● 使用 bael 和 babel-loader 编译 jsx、es6
● 安装插件: babel-preset-es2015 用于解析 es6
● 安装插件:babel-preset-react 用于解析 jsx
// 首先需要安装 babel
$ npm i babel-core
// 安装插件
$ npm i babel-preset-es2015babel-preset-react
// 安装 loader
$ npm i babel-loader
在项目根目录创建 .babelrc 文件:
{
"presets" : [ "es2015" , "react" ]
}
在 webpack.config.js 里添加:
// 使用缓存 var CACHE_PATH = ROOT_PATH + '/cache' ;
// loaders
config.mole. loaders = [];
// 使用 babel 编译 jsx 、 es6
config.mole. loaders .push({
test :/\.js$/,
exclude :/node_moles/,
include : SRC_PATH,
// 这里使用 loaders ,因为后面还需要添加 loader
loaders : [ 'babel?cacheDirectory=' + CACHE_PATH ]
});
接下来使用 sass-loader 编译 sass:
$ npm i sass-loader node-sasscss-loader style-loader
●css-loader 用于将 css 当做模块一样来 import
●style-loader 用于自动将 css 添加到页面
在 webpack.config.js 里添加:
// 编译 sass
config.mole. loaders .push({
test :/\.(scss|css)$/,
loaders : [ 'style' , 'css' , 'sass' ]
});
自动引入静态资源到相应 html 页面
● 使用 html-webpack-plugin
$ npm i html-webpack-plugin
在 webpack.config.js 里添加:
// html 页面 var HtmlwebpackPlugin= require( 'html-webpack-plugin' );
config.
plugins .push(
new HtmlwebpackPlugin({
filename : 'index.html' ,
chunks : [ 'app' ],
template : SRC_PATH + '/pages/app.html'
})
);
打包合并 js、css
webpack 默认将所有模块都打包成一个 bundle,并提供了 Code Splitting 功能便于我们按需拆分。在这个例子里我们把框架和库都拆分出来:
在 webpack.config.js 添加:
config.entry. lib = [
'react' , 'react-dom' , 'react-router' ,
'rex' , 'react-rex' , 'rex-thunk'
]
config.output. filename = 'js/[name].js' ;
config.
plugins .push(
new webpack.optimize.CommonsChunkPlugin( 'lib' , 'js/lib.js' )
);
// 别忘了将 lib 添加到 html 页面
// chunks: ['app', 'lib']
❸ 怎么快速上手JavaScript中的ES6,ES6中的解构,运算符,类,继承模块化 有什么简单的理解
模块化在项目中十分的重要,一个复杂的项目肯定有很多相似的功能模块,如果每次都需要重新编写模块肯定既费时又耗力。但是引用别人编写模块的前提是要有统一的“打开姿势”,如果每个人有各自的写法,那么肯定会乱套,下面介绍几种JS的模块化的规范。
一:模块化进程一:script标签
这是最原始的 JavaScript 文件加载方式,如果把每一个文件看做是一个模块,那么他们的接口通常是暴露在全局作用域下,也就是定义在 window 对象中,不同模块的接口调用都是一个作用域中,一些复杂的框架,会使用命名空间的概念来组织这些模块的接口。
缺点:
1、污染全局作用域
2、开发人员必须主观解决模块和代码库的依赖关系
3、文件只能按照script标签的书写顺序进行加载
4、在大型项目中各种资源难以管理,长期积累的问题导致代码库混乱不堪
二:模块化进程二:CommonJS规范
该规范的核心思想是允许模块通过require方法来同步加载所要依赖的其他模块,然后通过 exports 或 mole.exports 来导出需要暴露的接口。
require("mole");
require("../file.js");
exports.doStuff = function(){};
mole.exports = someValue;
优点:
1、简单并容易使用
2、服务器端模块便于重用
缺点:
1、同步的模块加载方式不适合在浏览器环境中,同步意味着阻塞加载,浏览器资源是异步加载的
2、不能非阻塞的并行加载多个模块
mole.exports与exports的区别
1、exports 是指向的 mole.exports 的引用
2、mole.exports 初始值为一个空对象 {},所以 exports 初始值也是 {}
3、require() 返回的是 mole.exports 而不是 exports
exports示例:
// app.js
var circle = require('./circle');
console.log(circle.area(4));
// circle.js
exports.area = function(r){
return r * r * Math.PI;
}
mole.exports示例:
// app.js
var area = require('./area');
console.log(area(4));
// area.js
mole.exports = function(r){
return r * r * Math.PI;
}
错误的情况:
// app.js
var area = require('./area');
console.log(area(4));
// area.js
exports = function(r){
return r * r * Math.PI;
}
其实是对 exports 进行了覆盖,也就是说 exports 指向了一块新的内存(内容为一个计算圆面积的函数),也就是说 exports 和 mole.exports 不再指向同一块内存,也就是说此时 exports 和 mole.exports 毫无联系,也就是说 mole.exports 指向的那块内存并没有做任何改变,仍然为一个空对象{},也就是说area.js导出了一个空对象,所以我们在 app.js 中调用 area(4) 会报 TypeError: object is not a function 的错误。
总结:当我们想让模块导出的是一个对象时, exports 和 mole.exports 均可使用(但 exports 也不能重新覆盖为一个新的对象),而当我们想导出非对象接口时,就必须也只能覆盖 mole.exports 。
三:模块化进程三:AMD规范
由于浏览器端的模块不能采用同步的方式加载,会影响后续模块的加载执行,因此AMD(Asynchronous Mole Definition异步模块定义)规范诞生了。
AMD标准中定义了以下两个API
1、require([mole], callback);
2、define(id, [depends], callback);
require接口用来加载一系列模块,define接口用来定义并暴露一个模块。
示例:
define("mole", ["dep1", "dep2"], function(d1, d2){
return someExportedValue;
});
require(["mole", "../file"], function(mole, file){ /* ... */ });
优点:
1、适合在浏览器环境中异步加载模块
2、可以并行加载多个模块
缺点:
1、提高了开发成本,代码的阅读和书写比较困难,模块定义方式的语义不顺畅
2、不符合通用的模块化思维方式,是一种妥协的实现
四:模块化进程四:CMD规范
CMD(Common Mole Definition)规范和AMD很相似,尽量保持简单,并与CommonJS和Node.js的 Moles 规范保持了很大的兼容性。在CMD规范中,一个模块就是一个文件。
示例:
define(function(require, exports, mole){
var $ = require('jquery');
var Spinning = require('./spinning');
exports.doSomething = ...
mole.exports = ...
})
优点:
1、依赖就近,延迟执行
2、可以很容易在 Node.js 中运行
缺点:
1、依赖 SPM 打包,模块的加载逻辑偏重
AMD和CMD的区别
AMD和CMD起来很相似,但是还是有一些细微的差别,让我们来看一下他们的区别在哪里:
1、对于依赖的模块,AMD是提前执行,CMD是延迟执行。
2、AMD推崇依赖前置;CMD推崇依赖就近,只有在用到某个模块的时候再去require。看代码:
// AMD
define(['./a', './b'], function(a, b){ // 依赖必须一开始就写好
a.doSomething()
// 此处略去 100 行
b.doSomething()
...
});
// CMD
define(function(require, exports, mole){
var a = require('./a')
a.doSomething()
// 此处略去 100 行
var b = require('./b')
// 依赖可以就近书写
b.doSomething()
// ...
});
3、AMD 的 API 默认是一个当多个用,CMD 的 API 严格区分,推崇职责单一。
五:模块化进程五:ES6模块化
EcmaScript6标准增加了JavaScript语言层面的模块体系定义。ES6 模块的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS和AMD模块,都只能在运行时确定这些东西。
在 ES6 中,我们使用export关键字来导出模块,使用import关键字引用模块。需要说明的是,ES6的这套标准和目前的标准没有直接关系,目前也很少有JS引擎能直接支持。因此Babel的做法实际上是将不被支持的import翻译成目前已被支持的require。
尽管目前使用import和require的区别不大(本质上是一回事),但依然强烈推荐使用import关键字,因为一旦JS引擎能够解析ES6的import关键字,整个实现方式就会和目前发生比较大的变化。如果目前就开始使用import关键字,将来代码的改动会非常小。
示例:
import "jquery";
export functiondoStuff(){}
mole "localMole" {}
优点:
1、容易进行静态分析
2、面向未来的 EcmaScript 标准
缺点:
1、原生浏览器端还没有实现该标准
2、全新的命令字,新版的 Node.js才支持
❹ 为什么我使用gulp-babel不能将es6编译成es5
需要安装babel-preset-es2015插件,才能把es6编译成es5
npm install --save-dev babel-preset-es2015
在gulpfile.js中增加presets
var gulp = require("gulp");
var babel = require("gulp-babel");
gulp.task("default", function () {
return gulp.src("src/app.js")
.pipe(babel({
presets: ['es2015']
}))
.pipe(gulp.dest("dist"));
});
❺ 如何让浏览器支持ES6中的import和export语法
然而, Babel默认只转换新的JavaScript句法(syntax),而不转换新的API,比如Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise等全局对象,以及一些定义在全局对象上的方法(比如Object.assign)都不会转码。而且像import和export这两个命令现在在任何浏览器中都是不支持的, 同时babel也无法将其转换为浏览器支持的ES5, 原因在于:
babel只是个翻译,假设a.js 里 import 了 b.js, 对a.js进行转码,只是翻译了a.js,并不会把b.js的内容给读取合并进来, 如果想在最终的某一个js里,包含 a.js,b.js 的代码,那就需要用到打包工具
所以我在这里讲解一下如何使用webpack工具将带有import和export语法的JS文件, 通过打包工具生成所有浏览器都支持的单个JS文件.
1. 下载node.js和webpack
Node.js是一个基于Chrome JavaScript运行时建立的平台, 用于方首凯便地搭建响应速度快、易于扩展的网络应用。可以说就是服务器端的JS. webpack是一个打包工具, 而它是依赖于node.js运行的.
下载node.js可以通过官网: http://nodejs.cn/download/
具体的安装步骤网上可以搜到很多, 这里不再赘述. 安装完毕后打开node.js自带的命令行工具
这里写图片描述
然后输入如下命令全局安装webpack工具
npm install -g webpack
接着通过命令行工具定位到你的工程文件的根目录下, 再次安装webpack到你的工程中
npm install webpack
2. 编写webpack.config.js文件
在根目录下创建webpack.config.js, 这个文件是用来描述一些要使用webpack工具进行打包的配置信息, 文件内容如下:
这里写图片描述
通过该文件可以使用webpack打包工具, webpack会从import.js进入, 对该文件中的内容进行编译并打包, 最终会在dist目录下生成打包好的文件bundle.js, 编译打包过程空弯中用到的工具在mole对象的loaders中声明, 这里使用了babel-loader来对JS文件进行编译(包括从ES6转换为ES5以及打包)
3. 创建import.js
创建一个import.js, 内容如下:
这里写图片描述
在该文件中通过ES6语法import从export.js中引入firstName和lastName变量. 并且通过console.log将引入的两个变量打印到控制台.
4. 创建export.js
这里写图片描述
在该文件中通过ES6语法export将文件中的几个变量作为模块输出给别的文件引用.
5. 创建HTML文件
在HTML文件中直接将webpack最终打包生成的bundle.js文件引入即可, 因为通过webpack工具已经将export.js和import.js的所有内容都打包到一个文件bundle.js中了, 因此在HTML文件中引入该文件即可以将两个JS文件中的代码都执行.
这里写图片描述
6. 配置.babelrc文件
在工程文件的根目录下创建一个.babelrc文件(注意前面有个点), 这个文件是用来描述我要根据什么样的规则、或者是将JS文件编译成什么版本的文件(比如说ES5). 该文件的内容如下:
这里写图片描述
7. 下载相关依赖模块
方式1: 可以像下面这样, 直接在项目根目录下创建一个package.json文件, 并且在文件中指定devDependencies对象, 在该对象中写上我编译及打包中所要使用到的依赖模块, 图片中的webpack就是用于打包的工具, 而其他的以babel开头的选项都是编译JS文件并打包所需要用到的依赖模块.
这里写图片描述
创建好package.json文件后, 在命令行中输入
npm install
npm工具就会根据该文件中devDependencies选项下载对应的依赖模块.
方式2(推荐): Ctrl+R打开运行, 然后输入cmd打开命令行工具, 通过命令行工斗芹闷具一个个安装, 这样可以直接通过npm去下载依赖模块最新的稳定的版本, 同时也不需要自己去记这些模块的版本号
npm install babelnpm install babel-clinpm install babel-corenpm install babel-loadernpm install babel-preset-es2015
8. 使用 webpack打包
使用命令行工具定位到项目的根目录下, 然后输入如下指令
webpack
等待一会儿就会发现工程文件的目录下多了一个dist文件夹, 里面放着的就是打包好了的bundle.js文件, 在HTML文件中通过下面的代码引入js文件
<script src="dist/bundle.js"></script>
然后在浏览器上运行html文件, 使用F12打开开发者工具, 就可以看到console选项中输出两行记录”Micheal”, “Jackson”
❻ 解决 Vue 浏览器兼容 edge safari ie 问题
最近做的一个Vue项目,遇到了在Edge浏览器,Safari(version: 9.xx)浏览器上打不开的问题。分别有以下报错:
Safari Error:
Edge Error:
const 和 ...(spread operator)语法都是ES6语法,这说明在Edge和safari 9 浏览器下都不支持ES6语法。带着这个判断,我去查了一下es6的浏览器支禅蠢枣持情况,果不其然,safari10以下和Edge14以下 和 IE 都不支持es6语法,具体ES6浏览器支持情况请参考以下表格:
Browser Support for ES6 (ECMAScript 2015)
找到问题的原因在于浏览器不支持ES6语法,所档帆以需要使用Babel去编译。接下来是如何在前端项目贺拆中配置babel,使能够将ES6编译成ES5语法:
注意 : 所有使用到了ES6语法的文件都需要配置在以上的 mole> rules> include 里面。
重新运行项目,刷新浏览器发现页面恢复正常。
这篇文章涉及到的前端技术包括: ES6的新特性 , babel的配置 ,等等。感兴趣的同学可以查看我的其他文章或者自行学习。
参考文献: From ES5 to ESNext