postCSS-loader配置,让css随心所欲
组件必不可少的一部分就是 css
,这里看下关于 css
的一些 loaders
。
npm install babel-loader babel-core babel-preset-es2015 --save-dev
npm 从 npm@3 之后不赞成自动安装
peerDependencies
,所有必须在package.json
里明确指定babel-core
这样的宿主依赖。
peerDependencies
字段,主要用来供插件指定其所需要的主软件的版本。更多可以见这里
如果是从babel 5升级到 babel 6,可以看这份指导
在webpack.config.js
里配置是比较推荐的方式:
module: {
loaders: [
{
test: /\.jsx?$/, // 匹配'js' or 'jsx' 后缀的文件类型
exclude: /(node_modules|bower_components)/, // 排除某些文件
loader: 'babel', // 使用'babel-loader'也是一样的
query: { // 参数
presets: ['es2015']
}
}
]
}
选项的写法有两种
一种是查询字符串的方式:
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel?presets[]=es2015'
}
]
}
另一种是指定 query
属性
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel',
query: {
presets: ['es2015']
}
}
]
}
babel-loader
还支持以下选项:
cacheDirectory
: 默认值是 false
。如果设置了这个参数,被转换的结果将会被缓存起来。当webpack 再次编译时,将会首先尝试从缓存中读取转换结果,以此避免资源浪费。如果该值为空(loader: ‘babel-loader?cacheDirectory’),loader
会使用系统默认的临时文件目录。
exclude: /(node_modules|bower_components)/
排除部分目录cacheDirectory
参数也可以让你的 loader
性能提升2倍!helper
扩展您可以改为要求babel
作为一个独立运行的模块,以避免重复。
下面的配置通过babel-plugin-transform-runtime
插件可以禁用babel向每个文件注入helper
需要先安装插件
npm install babel-plugin-transform-runtime --save
loaders: [
// the 'transform-runtime' plugin tells babel to require the runtime
// instead of inlining it.
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel',
query: {
presets: ['es2015'],
plugins: ['transform-runtime']
}
}
]
javascript是一个弱类型语言,变量类型不需要声明,运算过程中会根据需要自动转换类型,这个是js的优点,够灵活,编码简单,但是同时也是软肋。有时候,有些类型转换的bug无从查起,特别是在复杂的应用中。
Flow为Javascript添加了静态类型检查,以提高开发效率和代码质量。更明确的说,静态类型检查提供的好处像早期错误检查,帮助你发现一些只有在运行时才能发现的错误。
由于flow是用OCaml语言写的,npm上只有对应的二进制包。
npm install flow-bin
可者使用 Homebrew 安装
brew install flow
在项目目录下执行 flow init
,会生成一个 .flowconfig
文件
只需要在待检查的js文件头部添加一行注释
/* @flow */
然后在同一目录下运行flow check
即可。
flow server是为了提高检测效率的后台程序,支持在后台运行,并且只监测有修改的文件。
方法很简单,一条 flow 命令就能完成 Flow 服务器启动,文件检测,被更改文件的检测,即第一次使用 flow 命令会启动 Flow 服务器并且首次检测文件,再次使用 flow 命令会连接 Flow 服务器并且检测文件,之后使用 flow 命令时将会连接 Flow 服务器并且对修改过的文件进行检测。
/* @flow */ 只要带有这个注释,都会进行类型检测
/* @flow weak */ 只对有加类型声明的变量进行类型检测
不声明变量类型的时候,Flow 也会自动检查隐性存在的类型转换。但更为严谨的方式是显式声明变量的类型。
可以在代码里写上类型:
/* @flow */
// Changing the return type to number fixes the error
function foo(x: string, y: number): number {
return x.length * y;
}
foo('Hello', 42);
也可以这样:
/* @flow */
type T = number;
var x: T = 0;
下面是一个更详细的例子:
class People {
name: string;
constructor(name:string){
this.name = name
}
getAge():number{
return 18;
}
}
function getLength(param?:string):number {
/*param?:string传参类型什么,?表示此处可不传值;*/
/*\:number为函数返回值类型,如果没有return可不写或写void*/
var s:string = 'string';/*字符*/
var ss:String = new String('string');/*字符对象*/
/* s = ss*///类型不同,flow会报错
var n:number = 12;/*数字*/
var nn:Number = new Number(12);/*数字对象*/
var b:boolean = true;/*bool值,仅能为true/false*/
var bb:Boolean = new Boolean(true);/*bool值对象*/
var o:{prop1:number,prop2:string} = {
/*对象熟悉声明*/
prop1: 12,
prop2: '21123'
}
var v:void = undefined;/*undefined*/
var a:any = 'aa';/*任意类型,除undefined*/
var m:mixed = '1';/*任意类型+undefined*/
var mm:mixed = undefined;/*任意类型+undefined*/
var aa:Array = [1,2,3,4];/*数组内值类型声明*/
var P:Class = People;/*自定义类型声明*/
var p:People = new People('pt');/*自定义People类型*/
if (param) {
return param.length;
} else {
return 0;
}
}
Flow致力于支持最新的JavaScript标准。目前已经支持各种ES6特性如destructuring, classes, extended objects, optional function parameters,以及核心API扩展(比如Map, Set, Promise, 和 new methods on Object, Array, 和 Math)。其它特性(尤其是模块)正在开发中。Flow支持CommonJS / Node.js 规范的模块。
Flow 也已经支持 React。
在构建工具中添加flow检查的步骤。webpack和gulp都有对应的flow插件。
我们在项目中用到的插件: eslint-plugin-flow-vars
Flow官网最近访问不了,可以看这里:https://github.com/facebook/flow/tree/master/website/docs flow——A static type checker for javascript #32 flow–facebook出品的javascript静态类型检查器
最近我们前端组在做一个简易的文档系统,使用redux+mongodb。其中抛弃了Ajax,起用了Fetch。
XMLHttpRequest 是一个设计粗糙的 API,不符合关注分离(Separation of Concerns)的原则,配置和调用方式非常混乱,而且基于事件的异步模型写起来也没有现代的 Promise,generator/yield,async/await 友好。
Fetch 的出现就是为了解决 XHR 的问题,Fetch API 是基于 Promise 设计。
刚开始用的时候发现个问题,POST数据发现后端获取不到,GET方式是没有问题的。如:
fetch('/group/update', {
method: 'post',
body: JSON.stringify(params)
})
.then((response) => response.json())
.then((json) => dispatch(fetchUpdateGroupName(json, index)))
.catch((err) => (console.log('err:', err)))
以前一直用Jquery Ajax,很少情况需要设置Content-Type,而且看到有些博文介绍Fetch的时候说,Fetch()如果没有设置Content-Type,会自动获取。
后来还是被家优提醒,以下代码才是正确的设置:
fetch('/group/update', {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(params)
})
.then((response) => response.json())
.then((json) => dispatch(fetchUpdateGroupName(json, index)))
.catch((err) => (console.log('err:', err)))
注意: Fetch 支持几种数据类型的传输,其中包含Blob, BLOB (binary large object),表示二进制大对象。其中有个只读属性,Blob.type(),此时的 Content-Type 应设置为此值。
这里顺便记录下POST常见的Content-Type:
浏览器的原生 form 表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。
POST http://www.123.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8
title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3
使用表单上传文件时,必须让 form 的 enctyped 等于这个值, 上传图片时,我们经常会看到下面这样
POST http://www.example.com HTTP/1.1
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text"
title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png
PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--
如果我们使用 new FormData()作为数据主体提交,也需要设置这种类型。
把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。但也有些服务端语言还没有支持这种方式,例如 php 就无法通过 $_POST 对象从上面的请求中获得内容。这时候,需要自己动手处理下:在请求头中 Content-Type 为 application/json 时,从 php://input 里获得原始输入流,再 json_decode 成对象。