转载

前端构建实践--基于webpack的开箱即用的解决方案

起步

关于基础知识,已经一些比较科学的理念,不需要我啰嗦说明,大家可以去看 张云龙大神的github (以下简称这个为 fouber的博客 ).我直接看这篇博客的时候: 卧槽,这tm才是构建啊。

但是兴奋完了以后,有个很现实的问题:我怎么去实现呢?然后我就放弃了。

当然,去把它实现的想法,一直都有。但是,一方面现有的工具都不是很顺手,另一方面自己的积累也不够。

前段时间简单的看了下 webpack ,感觉有戏,就做了些初步探讨。并写了两篇文章,文章内容现在看有些小错误,但是整体的思想都有体现了(链接文末给出)。

webpack的入门文章,强烈推荐 webpack-howto ,有印象有翻译版的,E文不好的,可以去找一下。

1.组件开发

1.1理念

单从形式上,静态文件不是按类型分目录,而是按页面,甚至页面里的模块来分目录。

所以每个项目的静态文件一级目录,不应该是 js , css , img .这种目录结构随着项目变大,找文件就让你很烦躁。比如有个页面,要下线了,那么它对应的js,css,img应该也要删除,但是上面的目录结构,你很难去确定某个静态文件是不是只有这个页面引用。比较好的情况是,能够很容易的辨别能不能删,如果误删,构建的时候就报错。当然好处还有很多,这个 fouber的博客 里有很多说明,就不赘述了。

那么写一个首页,我可能希望这样写:

/index  /header   header.js   header.less   header.jsx   img/    1.png,2.png...  /body   ..类似header  /footer   ..类似header  index.less  logo.png  index.entry.js  

其中 index.entry.js 是首页的入口文件。一般就是引入各个模块的文件和自己另外的一些资源文件,然后再加一些整合的逻辑

//index.entry.js中 import React from 'react' import header from './header/header.js' import './index.less' import './logo.png'      //下面是业务逻辑代码  //按需加载可以使用require.ensure 或者 bundle-loader 

当然这是一种写法上的便利,你要想写出屎一样的代码,谁都拦不住你

1.2 实现

落实到实现上,webpack通过各种loader去实现各种类型资源的解析、引用、打包。这个配置好loaders就ok了。

不过这里,展开来讲,有很多细节: 比如图片的路径。打包后的 相对路径 和你开发时候的相对路径可能是不一样的。实际上,路径问题,很容易错误,不过 webpack 以及各种 loader 提供的选项还比较细,都有可行的解决方式。一个比较典型的loaders配置

 loaders: [   {    test: /[/.jsx|/.js ]$/,    exclude: /node_modules/,    loader: "babel-loader?stage=0&optional[]=runtime"   },   {    test: //.css$/,    loader: ExtractTextPlugin.extract('style-loader', 'css-loader')   },   {    test: //.less$/,    loader: ExtractTextPlugin.extract('style-loader', 'css-loader?sourceMap!postcss-loader!less-loader')   },   {    test: //.(png|jpg|gif)$/,    loader: 'url-loader?limit=10000&name=img/[name]-[hash].[ext]'   }    ]  

静态资源管理

静态资源管理系统 = 资源表 + 资源加载框架

资源加载框架,实际webpack已经基本把活全做了。

构建的时候,你的代码就表明了它所依赖的东西,异步加载通过 code splitting 相关技术,webpack打包的时候,都帮你自动管理。

那么,你只要对每个 entry 生成资源表(我叫做它 assets-map )就行了。使用webpack,多页面,有多个entry,多入口的配置也很简单

entry: {     entryName:'entryFilePath.js',     entryName1:'entryFilePath1.js'     //... } 

webpack打包完,会提供一个 stats 对象, webpack(config,function(err,stats){})
,这里有每个 chunk 的详细信息 ,利用这个对象,就可以去生成每个文件的 assets-map 。不过那么重要的东西,当然已经有开源的东西了, assets-webpack-plugins .下面是生成了 assets-map 的一个例子。hash戳是加载在后面当queryString还是当作文件名的一部分,都可以配置。

{       "webpack-coc/lib": {         "js": "/dist/webpack-coc/lib.js?v=ac46dc0f05a4cc181b911ad1b8058f71e6fbc87d"       },       "webpack-coc/common": {         "js": "/dist/webpack-coc/common.js?v=ef0de9675a8837209c4f",         "css": "/dist/webpack-coc/common.css?v=ef0de9675a8837209c4f"       },       "webpack-coc/index/index.entry": {         "js": "/dist/webpack-coc/index/index.entry.js?v=7e28f5d80d5d6001e7fe",         "css": "/dist/webpack-coc/index/index.entry.css?v=7e28f5d80d5d6001e7fe"       },       "webpack-coc/contact/contact.entry": {         "js": "/dist/webpack-coc/contact/contact.entry.js?v=b2e27e29b6fd11004a49"       },       "webpack-coc/other/other.entry": {         "js": "/dist/webpack-coc/other/other.entry.js?v=95edb51bcbc304ccd1ad"       } } 

后端解析下这个json,就可以在页面中生成和文件内容相关的唯一的资源文件的路径。

开箱即用的方案

上面两点的说明,表明 webpack 能满足要求,但是你真正有在实际中,还是有很多细节和坑的。

  1. 首先路径问题:

    js,css的路径

    img 的路径

    css中,引用的img的路径

    发布后,cdn指向的根路径

  2. libcommon 怎么处理

  3. 各种坑。比如大部分的开源项目, output.libraryTarget 都设置成 umd ,但是这是开发库用的,开发页面的时候, umd + externals + CommonChunkPlugin 几乎一定会报错。你需要把output.libraryTarget 设置成 var .

  4. 多个entry文件怎么办?开发加一个页面,就要去改一下配置文件,把entry加进去?这个显然不行,一个不够自动化,另外让大家操作配置文件,是件危险的事。

好了,说了那么多,硬广时间到了。推销一下自己的 构建的方案 .

思路和我之前发的两篇文章是一致的,读完 第一篇 会更好的理解这个工具要做的事。

基于gulp+webpack的"约定大于配置"的构建方案探讨

基于gulp+webpack的"约定大于配置"的构建方案探讨 2

正文到此结束
Loading...