如何使用typescript web开发和Webpack编写网页应用

上一篇文章 &中,我们知道了webpack的安装,接下来我们要学习如何使用webpack。
以下内容来自webpack文档(不是直译):&
简单的webpack使用
创建一个模块化的Javascript项目
创建一个文件件,在文件夹里面创建两个js文件,分别命名为cats.js、app.js,并使用CommonJs语法来创建文件内容。
cats.js文件内容:
var cats = ['dave', 'henry', 'martha'];
module.exports =
app.js(entry point)内容:
cats = require('./cats.js');
console.log(cats);
'entry point'即应用程序开始的地方,也是webpack开始跟踪模块之间依赖的地方。
给webpack一个人口文件(app.js),设置一个特殊的输出文件(app.bundle.js):
webpack &app.js &app.bundle.js
app.bundle.js部分内容:
由此可见,不仅app.js里面的内容被打包进app.bundle.js,app.js所依赖度cats.js也被打包了进来。webpack打包原理是边读边分析入口文件的依赖,分析入口文件依赖的文件的依赖,以此类推,只要有依赖都去分析并打包到输出文件(app.bundle.js)中,下图很直观的展示了webpack打包原理:
打包文件已打包好,现在可以用运行&node &&app.bundle.js&&命令看看输出内容(cats模块被输出出来了):
复杂的webpack使用
通过以上内容,我们大概知道了webpack是怎么打包运行的,现在我们来看看复杂一点的案例。
webpack&是一个非常灵活的模块打包工具。它提供了很多高级特性,但是不是所有的特性都是通过命令行来使用的。想要使用更多的webpack特性,需要创建配置文件。
在真实的webpack项目中,我们会将资源文件和打包文件分开组织在不同的文件夹中。在接下来的例子中我们将资源文件放在&src &文件夹中,打包文件放在&dist& &中。
我们最终的项目目录结构是这样的:
开始创建项目,创建文件夹及文件。
1.创建项目文件命名为demo
2.在demo文件夹中创建src和dist文件夹
3.在src文件夹中创建app.js、cats.js,内容和对应的上面的app.js、cats.js内容一样。
4.用以下命令初始化项目,创建package.json配置文件。
& npm&init&
5.安装webpack插件,并且讲webpack插件配置到package.json文件中
& npm&install webpack --save-dev
创建及配置webpack配置文件
1.创建webpack.config.js文件,内容为:
module.exports = {
entry: './src/app.js',
path: './dist',
filename: 'app.bundle.js'
2.有了配置文件后,就可以简单的用webpack命令进行打包了& .
&dist文件夹下就多了一个app.bundle.js文件.
3. 运行node &dist/app.bundle.js命令,又可以得到cats的数组列表。
& node&dist/app.bundle.js
['dave', 'henry', 'martha']
使用loaders
webpack只支持本地JavaScript模块,但是很多人使用ES2015、CoffeeScript、TypeScript等的转译器。webpack的&loaders&即可解决转译的问题。Loaders是特殊的模块,webpack用来加载其他的用别的语言写的模块到webpack可以识别的JavaScript中。例如,babel-loader使用Babel来加载ES2015文件。
'json-loader'加载JSON文件
Loaders可以是被链接的,的确有些时候你需要讲loaders链接在一起。例如。&yaml-loader&只能将YAML转换成JSON.因此,你需要将它链接到&json-loader&所以才可以使用。
用babel-loader转译ES2015
在这个例子中,我们将会告诉webpack通过Babel运行我们的资源文件所以我们可以使用ES2015的特性
1.安装Babel和presets:
& & npm install babel-core babel-preset-es2015
2.安装babel-loader:
& & npm install babel-loader --save-dev
3.添加一个以.babelrc命名的文件,并使用presets配置Babel
{ "presets": [ "es2015" ] }
4.修改 webpack.config.js使得'babel-loader'来处理所有.js结尾的文件
module.exports = {
entry: './src/app.js',
path: './dist',
filename: 'app.bundle.js',
loaders: [{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
其中exclude: /node_modules/配置是将node_modules文件下的内容排除在外,降低编译时间。
5.安装你想使用的libraries例如jquery
npm install jquery
babel-polyfill --save
现在我们使用--save代替之前使用的--save-dev,这些libraries将在运行时候使用。我们使用了babel-polyfill,因此在老的浏览器中ES2015 API是可用的。
6.修改src/app.js文件
import 'babel-polyfill';
import cats from './cats';
import $ from 'jquery';
$('&h1&Cats&/h1&').appendTo('body');
const ul = $('&ul&&/ul&').appendTo('body');
for (const cat of cats) {
$('&li&&/li&').text(cat).appendTo(ul);
7.用webpack打包模块
8. 加载index.html文件这个app才能运行起来
&!DOCTYPE html&
&metacharset="utf-8"&
&scriptsrc="dist/app.bundle.js"charset="utf-8"&&/script&
当你打开index.html时,你可以看到cats的内容列表
在你的工作流程中,通常你想做一些额外的包的处理。例如压缩文件便于客户端更快速的加载。插件可以解决这个问题。我们将会增加uglify插件到配置文件中:
const webpack = require('webpack');
module.exports = {
entry: './src/app.js',
path: './dist',
filename: 'app.bundle.js',
loaders: [{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel',
plugins: [
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
comments: false,
uglify插件包含在webpack里,所以不需要额外的引用模块,但是不是所有的都是这样,webpack不包含的插件,第三方插件或者自己写的插件是要包含额外的引用模块的。
阅读(...) 评论()(点击上方公众号,可快速关注)作者:dmyang的博客网址:/a/9526本篇主要介绍webpack的基本原理以及基于webpack搭建纯静态页面型前端项目工程化解决方案的思路。下篇(还没写完)探讨下对于Node.js作为后端的项目工程化、模块化、前后端共享代码、自动化部署的做法。关于webpack的更多用法和前端工程的讨论,可以到github /chemdemo/chemdemo.github.io/issues/10关于前端工程下面是百科关于“软件工程”的名词解释:软件工程是一门研究用工程化方法构建和维护有效的、实用的和高质量的软件的学科。其中,工程化是方法,是将软件研发的各个链路串接起来的工具。对于软件“工程化”,个人以为至少应当有如下特点:有IDE的支持,负责初始化工程、工程结构组织、debug、编译、打包等工作有固定或者约定的工程结构,规定软件所依赖的不同类别的资源的存放路径甚至代码的写法等软件依赖的资源可能来自软件开发者,也有可能是第三方,工程化需要集成对资源的获取、打包、发布、版本管理等能力和其他系统的集成,如CI系统、运维系统、监控系统等广泛意义上讲,前端也属于软件工程的范畴。但前端没有Eclipse、Visual Studio等为特定语言量身打造的IDE。因为前端不需要编译,即改即生效,在开发和调试时足够方便,只需要打开个浏览器即可完成,所以前端一般不会扯到“工程”这个概念。在很长一段时间里,前端很简单,比如下面简单的几行代码就能够成一个可运行前端应用:&!DOCTYPE html&&html&&head&&title&webapp&/title&&link rel=&stylesheet& href=&app.css&&&/head&&body&&h1&app title&/h1&&script src=&app.js&&&/script&&/body&&/html&但随着webapp的复杂程度不断在增加,前端也在变得很庞大和复杂,按照传统的开发方式会让前端失控:代码庞大难以维护、性能优化难做、开发成本变高。感谢Node.js,使得JavaScript这门前端的主力语言突破了浏览器环境的限制可以独立运行在OS之上,这让JavaScript拥有了文件IO、网络IO的能力,前端可以根据需要任意定制研发辅助工具。一时间出现了以Grunt、Gulp为代表的一批前端构建工具,“前端工程”这个概念逐渐被强调和重视。但是由于前端的复杂性和特殊性,前端工程化一直很难做,构建工具有太多局限性。诚如 张云龙@fouber 所言:前端是一种特殊的GUI软件,它有两个特殊性:一是前端由三种编程语言组成,二是前端代码在用户端运行时增量安装。html、css和js的配合才能保证webapp的运行,增量安装是按需加载的需要。开发完成后输出三种以上不同格式的静态资源,静态资源之间有可能存在互相依赖关系,最终构成一个复杂的资源依赖树(甚至网)。所以,前端工程,最起码需要解决以下问题:提供开发所需的一整套运行环境,这和IDE作用类似资源管理,包括资源获取、依赖处理、实时更新、按需加载、公共模块管理等打通研发链路的各个环节,debug、mock、proxy、test、build、deploy等其中,资源管理是前端最需要也是最难做的一个环节。注:个人以为,与前端工程化对应的另一个重要的领域是前端组件化,前者属于工具,解决研发效率问题,后者属于前端生态,解决代码复用的问题,本篇对于后者不做深入。在此以开发一个多页面型webapp为例,给出上面所提出的问题的解决方案。前端开发环境搭建主要目录结构- webapp/
# webapp根目录- src/
# 开发目录+ css/
# css资源目录+ img/
# webapp图片资源目录- js/
# webapp js&jsx资源目录
- components/
# 标准组件存放目录
# 组件foo的样式
# 组件foo的逻辑
# 组件foo的模板
# 组件foo的入口
# 第三方纯js库
# 根据项目需要任意添加的代码目录+ tmpl/
# webapp前端模板资源目录a.html
# webapp入口文件ab.html
# webapp入口文件b- assets/
# 编译输出目录,即发布目录+ js/
# 编译输出的js目录+ img/
# 编译输出的图片目录+ css/
# 编译输出的css目录a.html
# 编译输出的入口ab.html
# 编译处理后的入口b+ mock/
# 假数据目录app.js
# 本地server入口routes.js
# 本地路由配置webpack.config.js
# webpack配置文件gulpfile.js
# gulp任务配置package.json
# 项目配置README.md
# 项目说明这是个经典的前端项目目录结构,项目目结构在一定程度上约定了开发规范。业务开发的同学只需关注src目录即可,开发时尽可能最小化模块粒度,这是异步加载的需要。assets是整个工程的产出,无需关注里边的内容是什么,至于怎么打包和解决资源依赖的,往下看。本地开发环境我们使用开源web框架搭建一个webserver,便于本地开发和调试,以及灵活地处理前端路由,以koa为例,主要代码如下:// app.jsvar http = require('http');var koa = require('koa');var serve = require('koa-static');var app = koa();var debug = process.env.NODE_ENV !== 'production';// 开发环境和生产环境对应不同的目录var viewDir = debug ? 'src' : 'assets';// 处理静态资源和入口文件app.use(serve(path.resolve(__dirname, viewDir), {maxage: 0}));app = http.createServer(app.callback());app.listen(3005, '0.0.0.0', function() {console.log('app listen success.');});运行node app启动本地server,浏览器输入 http://localhost:8080/a.html 即可看到页面内容,最基本的环境就算搭建完成。如果只是处理静态资源请求,可以有很多的替代方案,如Fiddler替换文件、本地起Nginx服务器等等。搭建一个Web服务器,个性化地定制开发环境用于提升开发效率,如处理动态请求、dnsproxy(多用于解决移动端配置host的问题)等,总之local webserver拥有无限的可能。定制动态请求我们的local server是localhost域,在ajax请求时为了突破前端同源策略的限制,本地server需支持代理其他域下的api的功能,即proxy。同时还要支持对未完成的api进行mock的功能。// app.jsvar router = require('koa-router')();var routes = require('./routes');routes(router, app);app.use(router.routes());// routes.jsvar proxy = require('koa-proxy');var list = require('./mock/list');module.exports = function(router, app) {// mock api// 可以根据需要任意定制接口的返回router.get('/api/list', function*() {
var query = this.query || {};
var offset = query.offset || 0;
var limit = query.limit || 10;
var diff = limit - list.
if(diff &= 0) {
this.body = {code: 0, data: list.slice(0, limit)};
var arr = list.slice(0, list.length);
var i = 0;
while(diff--) arr.push(arr[i++]);
this.body = {code: 0, data: arr};
}});// proxy apirouter.get('/api/foo/bar', proxy({url: ''}));}webpack资源管理资源的获取ECMAScript 6之前,前端的模块化一直没有统一的标准,仅前端包管理系统就有好几个。所以任何一个库实现的loader都不得不去兼容基于多种模块化标准开发的模块。webpack同时提供了对CommonJS、AMD和ES6模块化标准的支持,对于非前三种标准开发的模块,webpack提供了shimming modules的功能。受Node.js的影响,越来越多的前端开发者开始采用CommonJS作为模块开发标准,npm已经逐渐成为前端模块的托管平台,这大大降低了前后端模块复用的难度。在webpack配置项里,可以把node_modules路径添加到resolve search root列表里边,这样就可以直接load npm模块了:// webpack.config.jsresolve: {root: [process.cwd() + '/src', process.cwd() + '/node_modules'],alias: {},extensions: ['', '.js', '.css', '.scss', '.ejs', '.png', '.jpg']},$ npm install jquery react --save// page-x.jsimport $ from 'jquery';import React from 'react';资源引用根据webpack的设计理念,所有资源都是“模块”,webpack内部实现了一套资源加载机制,这与Requirejs、Sea.js、Browserify等实现有所不同,除了借助插件体系加载不同类型的资源文件之外,webpack还对输出结果提供了非常精细的控制能力,开发者只需要根据需要调整参数即可:// webpack.config.js// webpack loaders的配置示例...loaders: [{
test: /\.(jpe?g|png|gif|svg)$/i,
loaders: [
'image?{bypassOnDebug: true, progressive:true, \
optimizationLevel: 3, pngquant:{quality: &65-80&}}',
'url?limit=10000&name=img/[hash:8].[name].[ext]',
test: /\.(woff|eot|ttf)$/i,
loader: 'url?limit=10000&name=fonts/[hash:8].[name].[ext]'},{test: /\.(tpl|ejs)$/, loader: 'ejs'},{test: /\.js$/, loader: 'jsx'},{test: /\.css$/, loader: 'style!css'},{test: /\.scss$/, loader: 'style!css!scss'},]...简单解释下上面的代码, test 项表示匹配的资源类型, loader 或 loaders 项表示用来加载这种类型的资源的loader,loader的使用可以参考using loaders,更多的loader可以参考list of loaders。对于开发者来说,使用loader很简单,最好先配置好特定类型的资源对应的loaders,在业务代码直接使用webpack提供的 require(source path) 接口即可:// a.js// 加载css资源require('../css/a.css');// 加载其他js资源var foo = require('./widgets/foo');var bar = require('./widgets/bar');// 加载图片资源var loadingImg = require('../img/loading.png');var img = document.createElement('img');img.src = loadingI注意,require()还支持在资源path前面指定loader,即 require(![loaders list]![source path]) 形式:require(&!style!css!less!bootstrap/less/bootstrap.less&);// “bootstrap.less”这个资源会先被&less-loader&处理,// 其结果又会被&css-loader&处理,接着是&style-loader&// 可类比pipe操作require() 时指定的loader会覆盖配置文件里对应的loader配置项。资源依赖处理通过loader机制,可以不需要做额外的转换即可加载浏览器不直接支持的资源类型,如 .scss 、 .less 、 .json 、 .ejs 等。但是对于css、js和图片,采用webpack加载和直接采用标签引用加载,有何不同呢?运行webpack的打包命令,可以得到 a.js 的输出的结果:webpackJsonp([0], {/***/0:/***/function(module, exports, __webpack_require__) {
__webpack_require__(6);
var foo = __webpack_require__(25);
var bar = __webpack_require__(26);
var loadingImg = __webpack_require__(24);
var img = document.createElement('img');
img.src = loadingI},/***/6:/***/function(module, exports, __webpack_require__) {
...},/***/7:/***/function(module, exports, __webpack_require__) {
...},/***/24:/***/function(module, exports) {
...},/***/25:/***/function(module, exports) {
...},/***/26:/***/function(module, exports) {
...}});从输出结果可以看到,webpack内部实现了一个全局的webpackJsonp()用于加载处理后的资源,并且webpack把资源进行重新编号,每一个资源成为一个模块,对应一个id,后边是模块的内部实现,而这些操作都是webpack内部处理的,使用者无需关心内部细节甚至输出结果。上面的输出代码,因篇幅限制删除了其他模块的内部实现细节,完整的输出请看a.out.js,来看看图片的输出:/***/24:/***/function(module, exports) {module.exports = &data:image/base64,...&;/***/}注意到图片资源的loader配置:{test: /\.(jpe?g|png|gif|svg)$/i,loaders: [
'image?...',
'url?limit=10000&name=img/[hash:8].[name].[ext]',]}意思是,图片资源在加载时先压缩,然后当内容size小于~10KB时,会自动转成base64的方式内嵌进去,这样可以减少一个HTTP的请求。当图片大于10KB时,则会在img/下生成压缩后的图片,命名是 [hash:8].[name].[ext] 的形式。hash:8的意思是取图片内容hashsum值的前8位,这样做能够保证引用的是图片资源的最新修改版本,保证浏览器端能够即时更新。对于css文件,默认情况下webpack会把css content内嵌到js里边,运行时会使用 style 标签内联。如果希望将css使用 link 标签引入,可以使用 ExtractTextPlugin 插件进行提取。资源的编译输出webpack的三个概念:模块(module)、入口文件(entry)、分块(chunk)。其中,module指各种资源文件,如js、css、图片、svg、scss、less等等,一切资源皆被当做模块。webpack编译输出的文件包括以下2种:entry:入口,可以是一个或者多个资源合并而成,由html通过script标签引入chunk:被entry所依赖的额外的代码块,同样可以包含一个或者多个文件下面是一段entry和output项的配置示例:entry: {a: './src/js/a.js'},output: {path: path.resolve(debug ? '__build' : './assets/'),filename: debug ? '[name].js' : 'js/[chunkhash:8].[name].min.js',chunkFilename: debug ? '[chunkhash:8].chunk.js' : 'js/[chunkhash:8].chunk.min.js',publicPath: debug ? '/__build/' : ''}其中entry项是入口文件路径映射表,output项是对输出文件路径和名称的配置,占位符如[id]、[chunkhash]、[name]等分别代表编译后的模块id、chunk的hashnum值、chunk名等,可以任意组合决定最终输出的资源格式。hashnum的做法,基本上弱化了版本号的概念,版本迭代的时候chunk是否更新只取决于chnuk的内容是否发生变化。细心的同学可能会有疑问,entry表示入口文件,需要手动指定,那么chunk到底是什么,chunk是怎么生成的?在开发webapp时,总会有一些功能是使用过程中才会用到的,出于性能优化的需要,对于这部分资源我们希望做成异步加载,所以这部分的代码一般不用打包到入口文件里边。对于这一点,webpack提供了非常好的支持,即code splitting,即使用 require.ensure() 作为代码分割的标识。例如某个需求场景,根据url参数,加载不同的两个UI组件,示例代码如下:var component = getUrlQuery('component');if('dialog' === component) {require.ensure([], function(require) {
var dialog = require('./components/dialog');
// todo ...});}if('toast' === component) {require.ensure([], function(require) {
var toast = require('./components/toast');
// todo ...});}url分别输入不同的参数后得到瀑布图:webpack将 require.ensure() 包裹的部分单独打包了,即图中看到的 [hash].chunk.js ,既解决了异步加载的问题,又保证了加载到的是最新的chunk的内容。假设app还有一个入口页面b.html,那麽就需要相应的再增加一个入口文件b.js,直接在entry项配置即可。多个入口文件之间可能公用一个模块,可以使用 CommonsChunkPlugin 插件对指定的chunks进行公共模块的提取,下面代码示例演示提取所有入口文件公用的模块,将其独立打包:var chunks = Object.keys(entries);plugins: [new CommonsChunkPlugin({
name: 'vendors', // 将公共模块提取,生成名为`vendors`的chunk
chunks: chunks,
minChunks: chunks.length // 提取所有entry共同依赖的模块})],资源的实时更新引用模块,webpack提供了 require() API(也可以通过添加bable插件来支持ES6的 import 语法)。但是在开发阶段不可能改一次编译一次,webpack提供了强大的热更新支持,即HMR(hot module replace)。HMR简单说就是webpack启动一个本地webserver(webpack-dev-server),负责处理由webpack生成的静态资源请求。注意webpack-dev-server是把所有资源存储在内存的,所以你会发现在本地没有生成对应的chunk访问却正常。下面这张来自webpack官网的图片,可以很清晰地说明module、entry、chunk三者的关系以及webpack如何实现热更新的:enter0表示入口文件,chunk1~4分别是提取公共模块所生成的资源块,当模块4和9发生改变时,因为模块4被打包在chunk1中,模块9打包在chunk3中,所以HMR runtime会将变更部分同步到chunk1和chunk3中对应的模块,从而达到hot replace。webpack-dev-server的启动很简单,配置完成之后可以通过cli启动,然后在页面引入入口文件时添加webpack-dev-server的host即可将HMR集成到已有服务器:...&body&...&script src=&http://localhost:8080/__build/vendors.js&&&/script&&script src=&http://localhost:8080/__build/a.js&&&/script&&/body&...因为我们的local server就是基于Node.js的webserver,这里可以更进一步,将webpack开发服务器以中间件的形式集成到local webserver,不需要cli方式启动(少开一个cmd tab):// app.jsvar webpackDevMiddleware = require('koa-webpack-dev-middleware');var webpack = require('webpack');var webpackConf = require('./webpack.config');app.use(webpackDevMiddleware(webpack(webpackConf), {contentBase: webpackConf.output.path,publicPath: webpackConf.output.publicPath,hot: true,stats: webpackConf.devServer.stats}));启动HMR之后,每次保存都会重新编译生成新的chnuk,通过控制台的log,可以很直观地看到这一过程:公用代码的处理:封装组件webpack解决了资源依赖的问题,这使得封装组件变得很容易,例如:// js/components/component-x.jsrequire('./component-x.css');// &a href='/members/'&@see&/a& /okonet/ejs-loadervar template = require('./component-x.ejs');var str = template({foo: 'bar'});function someMethod() {}exports.someMethod = someM使用:// js/a.jsimport {someMethod} from &./components/component-x&;someMethod();正如开头所说,将三种语言、多种资源合并成js来管理,大大降低了维护成本。对于新开发的组件或library,建议推送到 npm 仓库进行共享。如果需要支持其他加载方式(如RequireJS或标签直接引入),可以参考webpack提供的externals项。资源路径切换由于入口文件是手动使用script引入的,在webpack编译之后入口文件的名称和路径一般会改变,即开发环境和生产环境引用的路径不同:// 开发环境// a.html&script src=&/__build/vendors.js&&&/script&&script src=&/__build/a.js&&&/script&// 生产环境// a.html&script src=&/js/460de4b8.vendors.min.js&&&/script&&script src=&/js/e7d20340.a.min.js&&&/script&webpack提供了 HtmlWebpackPlugin 插件来解决这个问题,HtmlWebpackPlugin支持从模板生成html文件,生成的html里边可以正确解决js打包之后的路径、文件名问题,配置示例:// webpack.config.jsplugins: [new HtmlWebpackPlugin({
template: './src/a.html',
filename: 'a',
inject: 'body',
chunks: ['vendors', 'a']})]这里资源根路径的配置在 output 项:// webpack.config.jsoutput: {...publicPath: debug ? '/__build/' : '/'}其他入口html文件采用类似处理方式。辅助工具集成local server解决本地开发环境的问题,webpack解决开发和生产环境资源依赖管理的问题。在项目开发中,可能会有许多额外的任务需要完成,比如对于使用compass生成sprites的项目,因目前webpack还不直接支持sprites,所以还需要compass watch,再比如工程的远程部署等,所以需要使用一些构建工具或者脚本的配合,打通研发的链路。因为每个团队在部署代码、单元测试、自动化测试、发布等方面做法都不同,前端需要遵循公司的标准进行自动化的整合,这部分不深入了。对比&综述前端工程化的建设,早期的做法是使用Grunt、Gulp等构建工具。但本质上它们只是一个任务调度器,将功能独立的任务拆解出来,按需组合运行任务。如果要完成前端工程化,这两者配置门槛很高,每一个任务都需要开发者自行使用插件解决,而且对于资源的依赖管理能力太弱。在国内,百度出品的fis也是一种不错的工程化工具的选择,fis内部也解决了资源依赖管理的问题。因笔者没有在项目中实践过fis,所以不进行更多的评价。webpack以一种非常优雅的方式解决了前端资源依赖管理的问题,它在内部已经集成了许多资源依赖处理的细节,但是对于使用者而言只需要做少量的配置,再结合构建工具,很容易搭建一套前端工程解决方案。基于webpack的前端自动化工具,可以自由组合各种开源技术栈(Koa/Express/其他web框架、webpack、Sass/Less/Stylus、Gulp/Grunt等),没有复杂的资源依赖配置,工程结构也相对简单和灵活。附上笔者根据本篇的理论所完成的一个前端自动化解决方案项目模板:webpack-bootstrap:/chemdemo/webpack-bootstrap(完)。前端大全微信号:FrontDev打造东半球最好的 前端技术 微信号--------------------------------------商务合作QQ:投稿网址:前端大全(FrontDev) 
 文章为作者独立观点,不代表WtouTiao文章网立场
的最新文章
分页是一个很简单,通用的功能。作为一个有经验的前端开发人员,有义务把代码中类似这样公共的基础性的东西抽象出来,一来是改善代码的整体质量,更重要的是为了将来做类似的功能或者类似的项目,能减少不必要的重复工作量。Underscore.js 是一个由 Jeremy Ashkenas 开发的 JavaScript 库,它提供了许多作为开发者的我们在开发 Web 项目所需要的实用功能。今天我们来看一看 TypeScript,它是一种可以编译成 JavaScript 的编程语言,是为构建大型复杂应用程序的开发者们而设计的。所谓单页应用,指的是在一个页面上集成多种功能,甚至整个系统就只有一个页面,所有的业务功能都是它的子模块,通过特定的方式挂接到主界面上。它是AJAX技术的进一步升华,把AJAX的无刷新机制发挥到极致,因此能造就与桌面程序媲美的流畅用户体验。曾有人调侃,设计模式是工程师用于跟别人显摆的,显得高大上;也曾有人这么说,不是设计模式没用,是你还没有到能懂它,会用它的时候。说到 React 组件,肯定离不开组件的 props 和 state,我们可以在 props 和 state 存放任何类型的数据,通过改变 props 和 state,去控制整个组件的状态。W3C 使用特定的语法来定义所有可能在 CSS 属性中使用的值。如果你曾经看过 CSS 规范,你可能已经见过这种语法的使用 – 比如 border-image-slice 语法。用 CSS3 绘制你需要的几何图形。圆形,思路:给任何正方形元素设置一个足够大的 border-radius ,就可以把它变成一个圆形.卤煮在公司之初接触到的是一个微信APP应用。前端技术采用的是Backbone+zepto等小型JS类库。在项目开发之初,这类中小型的项目采用这两种库可以满足基本的需求。算起来已经足足两个半月没有更新文章,这段时间过得比较忙:夜间跑步计划、卖房买房以及工作上各种事情都凑到一块了。实际上,最近也并没有忙到完全抽不出时间写博客这种地步,根本原因可能还是变懒了,这样不好。那天和boss聊天,不经意间提到了Meteor,然后聊到了WebSocket,然后就有了以下对话,不得不说,看问题的方式不同,看到的东西也会大不相同。在前两章,为了方便调试,我们写了一个非常简单的 jQuery.fn.init 方法JavaScript 的格局日新月异,网站和应用的依赖关系也随之而变。这篇文章适合那些大量使用 script 标签来加载 JS 的程序员,随着网页数目增多和项目规模的扩大,他们感觉到依赖管理变得越来越笨重。无论编码能力如何,我们都会犯错。不仅自己代码中会有 bug,多数的 web 应用是由团队创建的,所以队友和你一样,都有可能犯错。此外,接手遗留代码意味着同时继承了其它团队的 bug。在此情况下,调试技巧就派上用场了。Node.js 让 JavaScript 编写服务器端应用程序成为可能。它建立在 JavaScript V8运行时之上,所以它很快。最初,它旨在为应用程序提供服务器环境,但是开发人员开始利用它来创建工具,帮助他们本地的任务自动化。我们从一些小测试开始。以下情况都会弹出什么结果?由于最近做了一些页面的动画效果,之前经验不多,这次做的过程中碰到些问题,加之很早前就阅读过一篇很好介绍动画的博客《关于动画,你需要知道的》,来自十年踪迹,所以就思考了一些关于动画的基本原理的问题,比如本文这个。HTTP 协议是互联网的基础协议,也是网页开发的必备知识,最新版本 HTTP/2 更是让它成为技术热点。不看不知道,一看吓一跳,已经整整一个月没有更新 underscore 源码解读系列文章了。前面我们已经完成了 Object ,Array,Collection 上的扩展方法的源码剖析,本文开始来解读 Function 上的扩展方法。回想n年前刚写前端的时候,在处理一个’鼠标hover切换背景图会闪’的问题时,将两张背景图合成一张图片,顺利解决问题。这应该是我第一次用到雪碧图的情况。受到好文《Web开发的发展史》(英文)激发的灵感,写下我对web开发技术的认识。
大学时候,上机还得换卡穿拖鞋,Novell的网络是很神奇的,然而更神奇的是通讯原理老师半神秘的讲他上 InternetArunr 把过去 15 年以来,Web开发从最初的纯 HTML 到 CGI、PHP\JSP\ASP、Ajax、Rails、NodeJS 这个过程简要地进行了介绍。Arunr 计划把这个作为一个大纲,接下来把每一部分详细地写点东西。看完 Collection Functions 部分的源码,首先迫不及待想跟大家分享的正是本文主题 —— 数组乱序。这是一道经典的前端面试题,给你一个数组,将其打乱,返回新的数组,即为数组乱序,也称为洗牌问题。在日常的前端开发中,我们会遇到 LESS/SASS 编译、CSS 前缀自动补全 、CSS 压缩、 图片压缩、JS 合并压缩、布署发布 等各种各样的操作。通常,我们都会根据实际情况定制一个 流程 性的工具来实现所有常规的功能underscore 给数组(以及 arguments,这里特别说明下,underscore 的数组扩展方法,同样适用于 arguments)增加了 20 个扩展方法本篇文章并没有单纯的罗列出前端开发涉及到的技术栈,而是探寻这些技术栈背后的『秘密』,适合初学者以及想要了解这些『秘密』的阅读者。CSS可以修改图片的颜色,没错,可以,眼见为实!上面的不是很黑的是原始图标,是个PNG图片,下面这个是可以赋色的在过去的几年里,网站进化成了复杂的网页应用。曾经的互联网只涉及到简单的商业信息展现,而如今,看看 Facebook、Slack、Spotify 以及 Netflix,互联网正在改变你的社交和生活方式。最近在研究页面渲染及web动画的性能问题,以及拜读《CSS SECRET》(CSS揭秘)这本大作。本文主要想谈谈页面优化之滚动优化。最近开始看 underscore源码,并将 underscore源码解读 放在了我的 2016计划 中。
阅读一些著名框架类库的源码,就好像和一个个大师对话,你会学到很多。为什么是 underscore?对 JavaScript 程序员来说,处理回调是家常,但是处理层次过深的回调就没有那么美好了,下面的示例代码片段用了三层回调,再补脑一下更多层的场景,简直是酸爽,这就是传说中的回调地狱。以前看过一套 JavaScript 题目,借花献佛拿出来分享一下。附带了自己的理解和答案。有争议的地方,欢迎大家指出和讨论。writing-mode这个CSS属性,我们是不是很少见到,很少用到!我们往往称不常见的东西为“生僻”,就像是不常见的文字我们叫“生僻字”,因此不常见的CSS属性,我们可以叫做“生僻属性”关于 JavaScript,就算什么都不记得了,也请牢记这一点:它是阻塞式的。想象一下,你的浏览器是靠一个神奇的小精灵来运行的。Backbone中主要的业务逻辑位于Model和Collection,上一篇介绍了Backbone中的Model,这篇文章中将主要探讨Collection的源码。ECMAScrip 6 之前,JavaScript 是天生模块化缺失的,代码之间隔离最基本的单位是函数,通常 JavaScript 的模块化也是采用函数来实现。JavaScript 采用词法作用域(lexical scoping),函数执行依赖的变量作用域是由函数定义的时候决定,而不是函数执行的时候决定。无线页面本就分秒必争,更不用说当我们在无线页面中使用动画的时候。不管是css动画还是canvas动画,我们都需要时刻小心着,并且有必要掌握页面性能的基本分析方法。工作中可能会用到的小工具,在此记录一下。可以实现的功能有:本地http服务器,页面实时刷新,可以模拟ajax请求之前学习 react+webpack ,偶然路过 webpack 官网 ,看到顶部的 LOGO ,就很感兴趣。最近觉得自己 CSS3 过于薄弱,想着深入学习一番,遂以这个 LOGO 为切入口,好好研究学习了一下相关的 CSS3 属性。JavaScript 可能是迄今为止最被误解的语言,它包含的许多美妙设计被其同样包含的糟糕设计所淹没,总体上给人的印象是一种没有做好充分设计的、稍显混乱的玩具语言。现在我们再重新梳理一下语言的基本特性,仔细分辨哪些是好的、哪些是坏的。上篇文章中,我介绍了 HTTP 协议中的 Accept-Encoding 和 Content-Encoding 机制。它可以很好地用于文本类响应正文的压缩,减少网络数据的传输,已被广泛使用。在 《一次 Node.js 应用内存暴涨分析》中,我们处理了一个 Node.js vm 引发的内存泄漏问题,处理过程也是比较艰辛。上一次我们简单的谈了一下font set和一些要注意的基本问题。今天我们继续字体这一话题,深入讲讲上次提到的“通用字体族”。首先是最常用的 serif 和 sans-serif 这两个通用字体族。性能优化一直是前端工作中十分重要的一环,都说从 10 到 1 容易,从 1 到 0 很难。而随着前端技术的飞速发展,没有什么技术或者法则是金科玉律一沉不变的。很佩服那些勇于挑战权威,推陈出新的勇者,是他们让我们的技术不断的变革更加的卓越。在传统MVC框架模式中,Model承担业务逻辑的任务。Backbone作为一个mvc框架,主要的业务逻辑交由Model与Collection来实现。Model代表领域对象,今天主要学一下Model源码中几个重要的函数。本文将对 jQuery each() 函数作一个比较全面的介绍。 each() 函数是 jQuery 中最重要也是最常用的函数之一。通过本文你将明白为什么 each() 函数如此大放异彩,同时还将详细介绍如何使用 each() 函数。本文介绍一个jquery的小技巧,能让任意组件对象都能支持类似DOM的事件管理,也就是说除了派发事件,添加或删除事件监听器,还能支持事件冒泡,阻止事件默认行为等等。CSS 动画已经存在很多年了,使用恰当可以很好地提高网站的用户体验,也正是由于其容易使用,就很可能出现性能低下的动画,从而降低了整个页面的运行效率。从春节回来开始直到现在,公司就像开了闸的西湖水一样进行着新陈更替,可以说开发团队算是重组了。眼看着身边发生这种情况,虽然没有什么想法但还是有了点想法,所以想写篇文章阐述一下。FrontDev分享 Web 前端相关的技术文章、工具资源、精选课程、热点资讯热门文章最新文章FrontDev分享 Web 前端相关的技术文章、工具资源、精选课程、热点资讯}

我要回帖

更多关于 webpack react 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信