详解前端模块化工具-webpack-阿里云开发者社区

开发者社区> 行者武松> 正文

详解前端模块化工具-webpack

简介:
+关注继续查看

webpack是一个module bundler,抛开博大精深的汉字问题,我们暂且管他叫'模块管理工具 '。随着js能做的事情越来越多,浏览器、服务器,js似乎无处不在,这时,使日渐增多的js代码变得合理有序就显得尤为必要,也应运而生了很多模块化工 具。从服务器端到浏览器端,从原生的没有模块系统的`<script>`到基于Commonjs和AMD规范的实现到ES6 modules。为了模块化和更好的模块化,我们总是走在探索的路上。

但是这些实现模块化的方法或多或少都有他们的缺点。比如说使用`<script>`标签导入js模块,顺序不好把握且我们需要自己梳理 可能的冲突和依赖;使用Commonjs规范来解决问题,它使我们在服务器端的模块得到了重用,但是在浏览器端,网络的请求都是异步的,无法并行的 require多个module。ES6 modules的实现也只是一小部分,并且想要得到所有浏览器的支持,相比还是需要相当的一段时间。

当然灵活的模块管理只是webpack的众多特性之一,它还有众多优秀的特性:


  1. - 它同时支持commonjs和AMD规范(甚至混合的形式); 
  2. - 它可以打成一个完整的包,也可以分成多个部分,在运行时异步加载(可以减少第一次加载的时间); 
  3. - 依赖在编译时即处理完毕,可以减少运行时包的大小; 
  4. - Loaders可以使文件在编译时得到预处理,这可以帮我们做很多事情,比如说模板的预编译,图片的base64处理; 
  5. - 丰富的和可扩展的插件可以适应多变的需求。 

一、webpack详解

最近在学习ES6和React相关的知识,为了更加方便自己写代码,给自己写了个脚手架generator-reactpack。生成的项目中可以看到一个基本的webpack.config.js文件:


  1. var webpack = require('webpack'); 
  2. module.exports = { 
  3.     entry: [ 
  4.         'webpack/hot/only-dev-server'
  5.         './js/app.js' 
  6.     ], 
  7.     output: { 
  8.         path: './build'
  9.         filename: 'bundle.js' 
  10.     }, 
  11.     module: { 
  12.         loaders: [ 
  13.         { test: /\.js?$/, loaders: ['react-hot''babel'], exclude:     /node_modules/ }, 
  14.         { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader'}, 
  15.         { test: /\.css$/, loader: "style!css" }, 
  16.         {test: /\.less/,loader: 'style-loader!css-loader!less-loader'
  17.         ] 
  18.     }, 
  19.     resolve:{ 
  20.         extensions:['','.js','.json'
  21.     }, 
  22.     plugins: [ 
  23.         new webpack.NoErrorsPlugin() 
  24.     ] 
  25. }; 

webpack.config.js文件通常放在项目的根目录中,它本身也是一个标准的Commonjs规范的模块。在导出的配置对象中有几个关键的参数:

1.entry

entry可以是个字符串或数组或者是对象。

当entry是个字符串的时候,用来定义入口文件:

1 entry: './js/main.js'

当entry是个数组的时候,里面同样包含入口js文件,另外一个参数可以是用来配置webpack提供的一个静态资源服务器,webpack- dev-server。webpack-dev-server会监控项目中每一个文件的变化,实时的进行构建,并且自动刷新页面:

1 entry: [
2     'webpack/hot/only-dev-server',
3     './js/app.js'
4 ]

当entry是个对象的时候,我们可以将不同的文件构建成不同的文件,按需使用,比如在我的hello页面中只要\<script src='build/Profile.js'></script>引入hello.js即可:

1 entry: {
2     hello: './js/hello.js',
3     form: './js/form.js'
4 }

2.output

output参数是个对象,用于定义构建后的文件的输出。其中包含path和filename:

1 output: {
2     path: './build',
3     filename: 'bundle.js'
4 }

当我们在entry中定义构建多个文件时,filename可以对应的更改为[name].js用于定义不同文件构建后的名字。

3.module

关于模块的加载相关,我们就定义在module.loaders中。这里通过正则表达式去匹配不同后缀的文件名,然后给它们定义不同的加载器。比如说给less文件定义串联的三个加载器(!用来定义级联关系):


  1. module: { 
  2.     loaders: [ 
  3.         { test: /\.js?$/, loaders: ['react-hot''babel'], exclude: /node_modules/ }, 
  4.         { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader'}, 
  5.         { test: /\.css$/, loader: "style!css" }, 
  6.         { test: /\.less/, loader: 'style-loader!css-loader!less-loader'
  7.     ] 

此外,还可以添加用来定义png、jpg这样的图片资源在小于10k时自动处理为base64图片的加载器:

1 { test: /\.(png|jpg)$/,loader: 'url-loader?limit=10000'}

给css和less还有图片添加了loader之后,我们不仅可以像在node中那样require js文件了,我们还可以require css、less甚至图片文件:

1 require('./bootstrap.css');
2 require('./myapp.less');
3 var img = document.createElement('img');
4 img.src = require('./glyph.png');

但是需要知道的是,这样require来的文件会内联到 js bundle中。如果我们需要把保留require的写法又想把css文件单独拿出来,可以使用下面提到的[extract-text-webpack-plugin]插件。

在 上面示例代码中配置的第一个loaders我们可以看到一个叫做react-hot的加载器。我的项目是用来学习react写相关代码的,所以配置了一个 react-hot加载器,通过它,可以实现对react组件的热替换。我们已经在entry参数中配置了`webpack/hot/only-dev- server`,所以我们只要在启动webpack开发服务器时开启--hot参数,就可以使用react-hot-loader了。在 package.json文件中这样定义:

1 "scripts": { 2 "start": "webpack-dev-server --hot --progress --colors", 3 "build": "webpack --progress --colors" 4 }

4.resolve

webpack在构建包的时候会按目录的进行文件的查找,resolve属性中的extensions数组中用于配置程序可以自行补全哪些文件后缀:

1 resolve:{
2     extensions:['','.js','.json']
3 }

然后我们想要加载一个js文件时,只要require('common')就可以加载common.js文件了。
5.plugin

webpack提供了[丰富的组件]用来满足不同的需求,当然我们也可以自行实现一个组件来满足自己的需求。在我的项目里面没有特殊的需求,于是便只是配置了NoErrorsPlugin插件,用来跳过编译时出错的代码并记录,使编译后运行时的包不会发生错误:

1 plugins: [
2     new webpack.NoErrorsPlugin()
3 ]

6.externals

当我们想在项目中require一些其他的类库或者API,而又不想让这些类库的源码被构建到运行时文件中,这在实际开发中很有必要。此时我们就可以通过配置externals参数来解决这个问题:

1 externals: {
2 "jquery": "jQuery" 3 }

这样我们就可以放心的在项目中使用这些API了:var jQuery = require("jquery");

7.context

当我们在require一个模块的时候,如果在require中包含变量,像这样:

1 require("./mods/" + name + ".js");

那么在编译的时候我们是不能知道具体的模块的。但这个时候,webpack也会为我们做些分析工作:

1.分析目录:'./mods';
2.提取正则表达式:'/^.*\.js$/';

于是这个时候为了更好地配合wenpack进行编译,我们可以给它指明路径,像在cake-webpack-config中所做的那样(我们在这里先忽略abcoption的作用):

1 var currentBase = process.cwd();
2 var context = abcOptions.options.context ? abcOptions.options.context :
3 path.isAbsolute(entryDir) ? entryDir : path.join(currentBase, entryDir);

二、why webpack?

webpack与gulp并不矛盾,甚至一起使用会得到最大化的利益,webpack与gulp。使用webpack进行assets编译,使用gulp进行打包似乎就是为了让它们各司其职,用其所长。

关于工具的定位

webpack的定位是module bundler,作为模块化工具,它的竞争对手看起来更像是[browserify],而不是[Gulp],基于流的自动化构建工具。然而事实也是这样的。  

功能和使用方式上的不同

webpack提供了一些非常实用的功能,像在前面我们体会到的那些,比如说图片的处理,resolve的处理,分开构建[webpack-code-splitting]等等 。 许多其他工具需要插件的功能,webpack只要配置一下就可以了。

有时候一个东西到底怎样,自己折腾一遍或许体会就更加深刻了。

三、拓展阅读

- [webpack]
- [cake-webpack-config]
- [webpack-howto]
- [webpack-compared]


作者:大额_skylar

来源:51CTO

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Win10的ubuntu子系统,搭建前端自动化工具
Win10安装ubuntu子系统 最新版win10下可以直接跑ubuntu镜像,直接入正题这里如果你不能操作是因为版本不是最新的,我这里是最新的win10直接是有这个功能的。勾选后会要求重启,确定即可 然后win键弹出搜索,输入bash可以打开bash on windows 接下来就是按照提示添加用户密码就行了 Ubuntu安装Nodejs 我们选择用NVM安装和管理nodejs nvm是一个开源的Node版本管理器,通过简单的bash脚本来管理、切换多个Node.js版本。
3600 0
看懂前端脚手架你需要这篇WEBPACK
Webpack 是当下最热门的前端资源模块化管理和打包工具。它可以将许多松散的模块按照依赖和规则打包成符合生产环境部署的前端资源。还可以将按需加载的模块进行代码分隔,等到实际需要的时候再异步加载。通过loader 的转换,任何形式的资源都可以视作模块,比如 CommonJs 模块、 AMD 模块、 ES6 模块、CSS、图片、 JSON、Coffeescript、 LESS 等。
1456 0
Vuex进阶篇——Module模块化学习(前端必会)
我之前发布了一篇vuex的基础,如果你巧妙的将它遗忘,这是个传送门,点击复习。 我也是一直在看vuex,里边需要了解的知识其实不少,但是因为项目并不常用,所以也总是忘记,今天整理下来,和大家谈谈vueX的模块化开发。
4867 0
Schema – 模块化,响应式的前端开发框架
  Schema 是一个模块化的,响应式的前端框架,方便,快捷地帮助您迅速启动你的 Web 项目。Schema 配备完整的创建多个视图的能力。从桌面显示器到移动设备,它的12列网格提供强大的灵活性。   Schema 借助了强大的 LESS,这使得代码结构干净简洁,超级容易维护。
815 0
+关注
行者武松
杀人者,打虎武松也。
17142
文章
2569
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载