webpack多页应用架构专题系列 1

来源:互联网 发布:警用冬季执勤服淘宝 编辑:程序博客网 时间:2024/06/15 06:46

第一章:一套配置吃天下

webpack配置常用部分有哪些?

前言

webpack的配置文件是一个node.js的module,用CommonJS风格来书写,形如:

module.exports = {    entry: "./entry",    output: {        path: __dirname + "/dist",        filename: "bundle.js"    }}

webpack的配置文件并没有固定的命名,也没有固定的路径要求,如果你直接用webpack来执行编译,那么webpack默认读取的将是当前目录下的webpack.config.js

$ pwd/d/xampp/htdocs/webpack-seed$ webpack # webpack此时读取的实际上是/d/xampp/htdocs/webpack-seed/webpack.config.js

如果你有其它命名的需要或是你有多份配置文件,可以使用--config参数传入路径:

$ webpack --config ./webpackConfig/dev.config.js

另外,在CLI执行webpack指令时可传入的参数(当然除了--config)实际上都可以在配置文件里面直接声明,我强烈建议可以的话尽量都在配置文件里写好,有需要的话写两份配置也好三份也好(反正配置文件间也是可以互相引用的,相同的部分就拆成一个module出来以供读取,最后拼成各种情况下需要的配置就好了)。

入口文件配置:entry参数

entry可以是字符串(单入口),可以是数组(多入口),但为了后续发展,请务必使用object,因为object中的key在webpack里相当于此入口的name,既可以后续用来拼生成文件的路径,也可以用来作为此入口的唯一标识。 我推荐的形式是这样的:

entry: { // pagesDir是前面准备好的入口文件集合目录的路径  'alert/index': path.resolve(pagesDir, `./alert/index/page`),   'index/login': path.resolve(pagesDir, `./index/login/page`),   'index/index': path.resolve(pagesDir, `./index/index/page`),},

对照我的脚手架项目[webpack-seed][3]的文件目录结构,就很清楚了:

├─src # 当前项目的源码    ├─pages # 各个页面独有的部分,如入口文件、只有该页面使用到的css、模板文件等    │  ├─alert # 业务模块    │  │  └─index # 具体页面    │  ├─index # 业务模块    │  │  ├─index # 具体页面    │  │  └─login # 具体页面

由于每一个入口文件都相当于entry里的一项,因此这样一项一项地来写实在是有点繁琐,我就稍微写了点代码来拼接这entry:

  var pageArr = [    'index/login',    'index/index',    'alert/index',  ];  var configEntry = {};  pageArr.forEach((page) => {    configEntry[page] = path.resolve(pagesDir, page + '/page');  });

输出文件:output参数

output参数告诉webpack以什么方式来生成/输出文件,值得注意的是,与entry不同,output相当于一套规则,所有的入口都必须使用这一套规则,不能针对某一个特定的入口来制定output规则。output参数里有这几个子参数是比较常用的:path、publicPath、filename、chunkFilename,这里先给个[webpack-seed][4]中的示例:

    output: {      path: buildDir, // var buildDir = path.resolve(__dirname, './build');      publicPath: '../../../../build/',      filename: '[name]/entry.js',    // [name]表示entry每一项中的key,用以批量指定生成后文件的名称      chunkFilename: '[id].bundle.js',    },

path

path参数表示生成文件的根目录,需要传入一个绝对路径。path参数和后面的filename参数共同组成入口文件的完整路径。

publicPath

publicPath参数表示的是一个URL路径(指向生成文件的根目录),用于生成css/js/图片/字体文件等资源的路径,以确保网页能正确地加载到这些资源。 publicPath参数跟path参数的区别是:path参数其实是针对本地文件系统的,而publicPath则针对的是浏览器;因此,publicPath既可以是一个相对路径,如示例中的'../../../../build/',也可以是一个绝对路径如http://www.xxxxx.com/。一般来说,我还是更推荐相对路径的写法,这样的话整体迁移起来非常方便。那什么时候用绝对路径呢?其实也很简单,当你的html文件跟其它资源放在不同的域名下的时候,就应该用绝对路径了,这种情况非常多见于后端渲染模板的场景。

filename

filename属性表示的是如何命名生成出来的入口文件,规则有以下三种:

  • [name],指代入口文件的name,也就是上面提到的entry参数的key,因此,我们可以在name里利用/,即可达到控制文件目录结构的效果。
  • [hash],指代本次编译的一个hash版本,值得注意的是,只要是在同一次编译过程中生成的文件,这个[hash]的值就是一样的;在缓存的层面来说,相当于一次全量的替换。
  • [chunkhash],指代的是当前chunk的一个hash版本,也就是说,在同一次编译中,每一个chunk的hash都是不一样的;而在两次编译中,如果某个chunk根本没有发生变化,那么该chunk的hash也就不会发生变化。这在缓存的层面上来说,就是把缓存的粒度精细到具体某个chunk,只要chunk不变,该chunk的浏览器缓存就可以继续使用。

下面来说说如何利用filename参数和path参数来设计入口文件的目录结构,如示例中的path: buildDir, // var buildDir = path.resolve(__dirname, './build');filename: '[name]/entry.js',那么对于key为'index/login'的入口文件,生成出来的路径就是build/index/login/entry.js了,怎么样,是不是很简单呢?

chunkFilename

chunkFilename参数与filename参数类似,都是用来定义生成文件的命名方式的,只不过,chunkFilename参数指定的是除入口文件外的chunk(这些chunk通常是由于webpack对代码的优化所形成的,比如因应实际运行的情况来异步加载)的命名。

各种Loader配置:module参数

webpack的核心实际上也只能针对js进行打包,那webpack一直号称能够打包任何资源是怎么一回事呢?原来,webpack拥有一个类似于插件的机制,名为Loader,通过Loader,webpack能够针对每一种特定的资源做出相应的处理。Loader的种类相当多,有些比较基础的是官方自己开发,而其它则是由webpack社区开源贡献出来的,这里是Loader的List:[list of loaders][5]。 而module正是配置什么资源使用哪个Loader的参数(因为就算是同一种资源,也可能有不同的Loader可以使用,当然不同Loader处理的手段不一样,最后结果也自然就不一样了)。module参数有几个子参数,但是最常用的自然还是loaders子参数,这里也仅对loaders子参数进行介绍。

loaders参数

loaders参数又有几个子参数,先给出一个官方示例:

module.loaders: [  {    // "test" is commonly used to match the file extension    test: /\.jsx$/,    // "include" is commonly used to match the directories    include: [      path.resolve(__dirname, "app/src"),      path.resolve(__dirname, "app/test")    ],    // "exclude" should be used to exclude exceptions    // try to prefer "include" when possible    // the "loader"    loader: "babel-loader"  }]

下面一一对这些子参数进行说明:

  • test参数用来指示当前配置项针对哪些资源,该值应是一个条件值(condition)。
  • exclude参数用来剔除掉需要忽略的资源,该值应是一个条件值(condition)。
  • include参数用来表示本loader配置仅针对哪些目录/文件,该值应是一个条件值(condition)。这个参数跟test参数的效果是一样的(官方文档也是这么写的),我也不明白为嘛有俩同样规则的参数,不过我们姑且可以自己来划分这两者的用途:test参数用来指示文件名(包括文件后缀),而include参数则用来指示目录;注意同时使用这两者的时候,实际上是and的关系。
  • loader/loaders参数,用来指示用哪个/哪些loader来处理目标资源,这俩货表达的其实是一个意思,只是写法不一样,我个人推荐用loader写成一行,多个loader间使用!分割,这种形式类似于管道的概念,又或者说是函数式编程。形如loader: 'css?!postcss!less',可以很明显地看出,目标资源先经less-loader处理过后将结果交给postcss-loader作进一步处理,然后最后再交给css-loader。

条件值(condition)可以是一个字符串(某个资源的文件系统绝对路径),可以是一个函数(官方文档里是有这么写,但既没有示例也没有说明,我也是醉了),可以是一个正则表达式(用来匹配资源的路径,最常用,强烈推荐!),最后,还可以是一个数组,数组的元素可以为上述三种类型,元素之间为与关系(既必须同时满足数组里的所有条件)。需要注意的是,loader是可以接受参数的,方式类似于URL参数,形如'css?minimize&-autoprefixer',具体每个loader接受什么参数请参考loader本身的文档(一般也就只能在github里看了)。

添加额外功能:plugins参数

这plugins参数相当于一个插槽位(类型是数组),你可以先按某个plugin要求的方式初始化好了以后,把初始化后的实例丢到这里来。

听说webpack连less/css也能打包?

前言

过去讲前端模块化、组件化,更多还是停留在js层面,毕竟js作为一种更典型的程序语言,在这方面的想象和操作空间都更大一些。但近年来,组件化要求得更多了,HTML/CSS/JS这三件套一件可都不能少(甚至包括其它类型的资源,比如说图片),而这样的组件,无疑是高内聚的。

文章简介

本文将介绍如何使用webpack来打包less/css(没用过sass,但毕竟也是通过loader来加载的,相信与less无异),首先是介绍相关的webpack plugin&loader,然后将介绍如何加载不同应用层次的less/css。

用到什么loader了?

在[《webpack多页应用架构系列(二):webpack配置常用部分有哪些?》][2]里我就说过,webpack的核心只能打包js文件,而js以外的资源都是靠loader进行转换或做出相应的处理的。下面我就来介绍打包less/css所需要的loader。

less-loader

针对less文件,我们首先需要使用less-loader来加载。less-loader会调用所依赖的less模块对less文件进行编译(包括@import语法)。至于说less-loader所接受的参数,实质上大部分是传递给less模块使用的参数,由于我本人应用less的程度不深,因此没有传任何参数、直接就使用了。如果你之前对less模块就已经有了一套配置的话,请参考[less-loader的文档][3]进行配置。

另外,less-loader并不会针对url()语法做特别的转换,因此,如果你想把url()语句里涉及到的文件(比如图片、字体文件等)也一并用webpack打包的话,就必须利用管道交给css-loader做进一步的处理。

css-loader

针对css文件,我们需要使用css-loader来加载.css-loader的功能比较强大,一些新颖的特性比如Local Scope或是CSS Modules都是支持的。

我目前只用到了css-loader的[压缩功能(Minification)][4],对于这个功能,有一点是需要注意的,那就是如果你的代码里也和我一样,有许多为了浏览器兼容性的废弃CSS代码的话,请务必关闭autoprefixer已避免你的废弃CSS代码被css-loader删除了,形如css?minimize&-autoprefixer

上面提到css-loader会对url()语句做处理,这里稍微再说两句。在less/css里的这url()语句,在css-loader看来,就跟require()语句是一样的,只要在webpack配置文件里定义好加载各类型资源的loader,那这url()语句实际上什么资源都能处理。一般我在url()语句都会以相对路径的方式(相对于此语句所在的less/css文件)来指定文件路径;请不要使用以/开头(即相对于网站根目录,因为对于文件系统来说,这明显是令人混淆的)的路径,尽管css-loader也可以通过设置root参数来适配。

postcss-loader

习惯用postcss的童鞋们有福啦,webpack可以通过postcss-loader来兼容postcss。由于postcss只算是一个加分项,因此这里也不作过多介绍,只介绍一下如何把postcss撘进webpack,不明白的童鞋麻烦先把postcss搞懂了再看。

放上我的脚手架项目的代码:

var precss       = require('precss');var autoprefixer = require('autoprefixer');module.exports = {    module: {        loaders: [            {                test:   /\.css$/,                exclude: /node_modules|bootstrap/,                loader: 'css?minimize&-autoprefixer!postcss',            }        ]    },    postcss: function () {        return [precss, autoprefixer({            remove: false,            browsers: ['ie >= 8', '> 1% in CN'],        })];    }}

从loader的配置'css?minimize&-autoprefixer!postcss'上看,实际上就是先让postcss-loader处理完了再传递给css-loader。而postcss项则是postcss-loader所接受的参数,实际上就是返回一个包含你所需要的postcss's plugins的数组啦,这些plugin有各自的初始化参数,不过这些都是postcss的内容了,这里就不做介绍了。

用到什么Plugin了?

加载less/css这一块主要用到的是extract-text-webpack-plugin(下文简称为ExtractTextPlugin吧),而且由于我用的是webpack 1,因此用的也是相对应webpack 1的版本([1的文档在这里不要搞错了哈][5])。

ExtractTextPlugin的作用是把各个chunk加载的css代码(可能是由less-loader转换过来的)合并成一个css文件并在页面加载的时候以<link>的形式进行加载。

相对于使用style-loader直接把css代码段跟js打包在一起并在页面加载时以inline的形式插入DOM,我还是更喜欢ExtractTextPlugin生成并加载CSS文件的形式;倒不是看不惯inline的css,只是用文件形式来加载的话会快很多,尤其后面介绍用webpack来生成HTML的时候,这<link>会直接生成在<head>里,那么在CSS的加载上就跟传统的前端页面没有差别了,体验非常棒。

ExtractTextPlugin的初始化参数不多,唯一的必填项是filename参数,也就是如何来命名生成的CSS文件。跟webpack配置里的output.filename参数类似,这ExtractTextPlugin的filename参数也允许使用变量,包括[id]、[name]和[contenthash];理论上来说如果只有一个chunk,那么不用这些变量,写死一个文件名也是可以的,但由于我们要做的是多页应用,必然存在多个chunk(至少每个entry都对应一个chunk啦)。这里我是这么设置的:

new ExtractTextPlugin('[name]/styles.css'), [name]对应的是chunk的name,我在webpack配置中是这样

[name]对应的是chunk的name,我在webpack配置中把各个entry的name都按index/indexindex/login这样的形式来设置了,那么最后css的路径就会像这样:build/index/index/styles.css,也就是跟chunk的js文件放一块了(js文件的路径形如build/index/index/entry.js)。

除了要把这初始化后的ExtractTextPlugin放到webpack配置中的plugins参数里,我们还要在loader配置里做相应的修改:

module.exports = {    module: {        loaders: [            {                test:   /\.css$/,                exclude: /node_modules|bootstrap/,                loader: ExtractTextPlugin.extract('css?minimize&-autoprefixer!postcss'),            }        ]    },}

如此一来,ExtractTextPlugin就算是配置好了。

如何加载不同应用层次的less/css

在我的设计中,有三种应用层次的less/css代码段:

  • 基础的、公用的代码段,包括CSS框架、在CSS框架上进行定制的CSS theme,基本上每个页面都会应用到这些CSS代码段。
  • 组件的代码段,这里的组件指的是你自己写的组件,而且组件本身含有js,并负责加载css以及其它逻辑。
  • 每个页面独有的CSS代码段,很可能只是对某些细节进行微调。

首先来回顾一下我设计的文件目录结构:

├─src # 当前项目的源码    ├─pages # 各个页面独有的部分,如入口文件、只有该页面使用到的css、模板文件等    │  ├─alert # 业务模块    │  │  └─index # 具体页面    │  ├─index # 业务模块    │  │  ├─index # 具体页面    │  │  └─login # 具体页面    │  │      └─templates # 如果一个页面的HTML比较复杂,可以分成多块再拼在一起    │  └─user # 业务模块    │      ├─edit-password # 具体页面    │      └─modify-info # 具体页面    └─public-resource # 各个页面使用到的公共资源        ├─components # 组件,可以是纯HTML,也可以包含js/css/image等,看自己需要        │  ├─footer # 页尾        │  ├─header # 页头        │  ├─side-menu # 侧边栏        │  └─top-nav # 顶部菜单        ├─config # 各种配置文件        ├─iconfont # iconfont的字体文件        ├─imgs # 公用的图片资源        ├─layout # UI布局,组织各个组件拼起来,因应需要可以有不同的布局套路        │  ├─layout # 具体的布局套路        │  └─layout-without-nav # 具体的布局套路        ├─less # less文件,用sass的也可以,又或者是纯css        │  ├─base-dir        │  ├─components-dir # 如果组件本身不需要js的,那么要加载组件的css比较困难,我建议可以直接用less来加载        │  └─base.less # 组织所有的less文件        ├─libs # 与业务逻辑无关的库都可以放到这里        └─logic # 业务逻辑

基础代码段

基础的CSS代码(实际上我的项目中用的都是less)我统一都放到src/public-resource/less目录里。我使用一个抽象的文件base.less将所有的less文件组织起来(利用@import),这样的话我用js加载起来就方便多了。

在我的脚手架项目([Array-Huang/webpack-seed][6])里,CSS框架我用的是bootstrap,并且使用了bootstrap-loader进行加载,因此就没有把bootstrap的CSS文件放到src/public-resource/less/base-dir目录里,这个目录里放的都是我定制的theme了。

src/public-resource/less/components-dir目录放的是某些第三方组件所用到的css,又或是不含js的组件所用到的css。其实这部分CSS是否应该归在下一类,我也考虑良久,只是由于归到下一类的话加载起来不方便,不方便原因如下:

  • 某些第三方库是要你自己加载CSS的,如果你打算写适配器来封装这些第三方库,那自然可以直接在适配器来加载CSS,这就属于下一类了;然而,有一些使用起来很简单的库,你还写适配器那就有点画蛇添足了。
  • 某些自己写的组件可能仅包含HTML和CSS,那么谁来加载CSS?

所以干脆还是交由base.less一并加载了算了。

我设计了一个common.page.js,并在每一个页面的入口文件里都首先加载这common.page.js,那么,只要我在这common.page.js里加载base.less,所有的页面都能享受到这份基础CSS代码段。

组件代码段

组件的代码我都放在了src/public-resource/components,每一个组件统一放在一个独立的目录,并由该组件的js负责加载其CSS。

页面代码段

页面独有的CSS我自然是放在该页面自己的目录里,利用该页面的入口文件进行加载。

最终生成的CSS代码都在哪?

由于我使用了ExtractTextPlugin,因此这些CSS代码最终都会生成到所属chunk的目录里成为一个CSS文件。

  • 基础代码段肯定是保存在CommonsChunkPlugin所生成的公共代码chunk所在的目录里了,在我的脚手架项目(Array-Huang/webpack-seed)里就是build/commons了(我的公共代码chunk的name是'commons')。
  • 组件代码段看情况,该组件用的页面多的话(大于CommonsChunkPlugin的minChunks参数)就会被归到跟基础代码段一起咯;反之,则哪个页面用到它,就放到哪个页面chunk的目录里咯。
  • 页面代码段就不用想了,肯定是在那个页面chunk的目录里了,毕竟才用了1次。

听说webpack连图片和字体也能打包?

前言

上一篇《听说webpack连less/css也能打包?》说到使用loader来加载CSS,这一篇来讲讲如何笼统地加载其它类型的资源。为什么强调是“笼统”呢?这是因为本文介绍的方法并不针对任何类型的资源,这意味着,什么类型的资源都能用,但效果也都只是有限的。

用的什么loader呢?

本文介绍俩loader:file-loader和url-loader。

file-loader

file-loader的主要功能是:把源文件迁移到指定的目录(可以简单理解为从源文件目录迁移到build目录),并返回新文件的路径(简单拼接而成)。

file-loader需要传入name参数,该参数接受以下变量(以下讨论的前提是:源文件src/public-resource/imgs/login-bg.jpg;在根目录内执行webpack命令,也就是当前的上下文环境与src目录同级):

  • [ext]:文件的后缀名,示例为'jpg'。
  • [name]:文件名本身,示例为'login-bg'。
  • [path]:相对于当前执行webpack命令的目录的相对路径(不含文件名本身),示例为'src/public-resource/imgs/'。这个参数我感觉用处不大,除非你想把迁移后的文件放回源文件的目录或其子目录里。
  • [hash]:源文件内容的hash,用于缓存解决方案

我的做法是,require('!file-loader?name=static/images/[name].[ext]!../imgs/login-bg.jpg'),这样login-bg.jpg的路径就变成static/images/login-bg.jpg了,注意这还不是完整的路径,最终还是要拼上webpack配置中的output.publicPath参数的;比如说我的output.publicPath参数是../../../../build/,那么最终从require()里获得的完整路径就会是../../../../build/static/images/login-bg.jpg了。

url-loader

url-loader的主要功能是:将源文件转换成DataUrl(声明文件mimetype的base64编码)。据我所知,在前端范畴里,图片和字体文件的DataUrl都是可以被浏览器所识别的,因此可以把图片和字体都转化成DataUrl收纳在HTML/CSS/JS文件里,以减少HTTP连接数。

url-loader主要接受以下参数:

  • limit参数,数据类型为整型,表示目标文件的体积大于多少字节就换用file-loader来处理了,不填则永远不会交给file-loader处理。例如require("url?limit=10000!./file.png");,表示如果目标文件大于10000字节,就交给file-loader处理了。
  • mimetype参数,前面说了,DataUrl是需要声明文件的mimetype的,因此我们可以通过这个参数来强行设置mimetype,不填写的话则默认从目标文件的后缀名进行判断。例如require("url?mimetype=image/png!./file.jpg");,强行把jpg当png使哈。
  • 一切file-loader的参数,这些参数会在启用file-loader时传参给file-loader,比如最重要的name参数。

实操演示

接下来还是用我的脚手架项目[webpack-seed][3]来介绍如何利用url-loader和file-loader来加载各类资源。

图片

这一块我是直接在webpack配置文件里设置的:

        {          // 图片加载器,雷同file-loader,更适合图片,可以将较小的图片转成base64,减少http请求          // 如下配置,将小于8192byte的图片转成base64码          test: /\.(png|jpg|gif)$/,          loader: 'url-loader?limit=8192&name=./static/img/[hash].[ext]',        },

由于使用了[hash],因此即便是不同页面引用了相同名字但实际内容不同的图片,也不会造成“覆盖”的情况出现;进一步讲,如果不同页面引用了在不同位置但实际内容相同的图片,这还可以归并成一张图片,方便浏览器缓存呢。

字体文件

这一块我也还是直接在webpack配置里配置的:

        {          // 专供iconfont方案使用的,后面会带一串时间戳,需要特别匹配到          test: /\.(woff|woff2|svg|eot|ttf)\??.*$/,          loader: 'file?name=./static/fonts/[name].[ext]',        },

需要声明的是,由于我使用的是阿里妈妈的iconfont方案,此方案加载字体文件的方式有一点点特殊,所以正则匹配的时候要注意一点,iconfont的CSS是这样的,你们看看就明白了:

@font-face {font-family: "iconfont";  src: url('iconfont.eot?t=1473142795'); /* IE9*/  src: url('iconfont.eot?t=1473142795#iefix') format('embedded-opentype'), /* IE6-IE8 */  url('iconfont.woff?t=1473142795') format('woff'), /* chrome, firefox */  url('iconfont.ttf?t=1473142795') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/  url('iconfont.svg?t=1473142795#iconfont') format('svg'); /* iOS 4.1- */}

其它资源

也许你会问,我们为什么还需要转移其它资源呢?直接引用不就可以了吗?

我之前也是这么做的,直接引用源文件目录src里的资源,比如说webuploader用到的swf文件,比如说用来兼容IE而又不需要打包的js文件。但是后来我发现,这样做的话,就导致部署上线的时候要把build目录和src目录同时放上去了;而且由于build目录和src目录同级,我就只能用build目录和src目录的上一级目录作为网站的根目录了(因为如果把build目录设为网站,用户就读取不到src目录了),反正就是各种的不方便。

那么,我是怎么做的呢?

我建了一个config文件,名为build-file.config.js,内容如下:

module.exports = {  js: {    xdomain: require('!file-loader?name=static/js/[name].[ext]!../../../vendor/ie-fix/xdomain.all.js'),    html5shiv: require('!file-loader?name=static/js/[name].[ext]!../../../vendor/ie-fix/html5shiv.min.js'),    respond: require('!file-loader?name=static/js/[name].[ext]!../../../vendor/ie-fix/respond.min.js'),  },  images: {    'login-bg': require('!file-loader?name=static/images/[name].[ext]!../imgs/login-bg.jpg'),  },};

这个config文件起到两个作用:

  1. 每次加载到这个config文件的时候,会执行那些require()语句,对目标文件进行转移(从src目录到build目录)。
  2. 调用目标文件的代码段,可以从这个config文件取出目标文件转移后的完整路径,例如我在src/public-resource/components/header/html.ejs里是这么用的:
<!DOCTYPE html><html lang="zh-cmn-Hans"><head>  <meta http-equiv="X-UA-Compatible" content="IE=edge" />  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />  <title><% if (pageTitle) { %> <%= pageTitle %> - <% } %> XXXX后台</title>  <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1" />   <meta name="renderer" content="webkit" />  <!--[if lt IE 10]>    <script src="<%= BUILD_FILE.js.xdomain %>" slave="<%= SERVER_API_URL %>cors-proxy.html"></script>    <script src="<%= BUILD_FILE.js.html5shiv %>"></script>  <![endif]--></head><body>  <!--[if lt IE 9]>    <script src="<%= BUILD_FILE.js.respond %>"></script>  <![endif]-->

恩,你可能会好奇这HTML里怎么能直接引用js的值,哈哈哈,超纲了超纲了,这是我后面要讲到的内容了。



0 0