wepback作为前端最热门的打包管理工具之一,学习一下是很有必要的,关于webpack的学习教程很多,并且官方也有对应的中文文档,所以本篇文章不再讲解如何使用webpack,而是重点讲解学习webpack前需要了解的一些概念。
什么是webpack
关于什么是webpack,一般的教程里面都会提到webpack是一个模块化打包工作,但是很多初学者没有模块化这个概念,所以往往在第一步就被拦住了。所以在讲什么是webpack之前,我想先讲一下和模块化相关的概念。
javascript的运行环境
因为我们平时写的js代码都在浏览器中运行,所以可能会造成一个错觉,那就是js代码只能在浏览器中运行,其实浏览器只是js的一个运行环境,除了在浏览器,还可以在服务器上运行,也就是node环境,感兴趣的可以自己下载node.js试一下,在node.js里面可以直接运行js代码。所以有些语法在浏览器里面并不支持,比如es6的module,即使在最新的浏览器里面也不行,这些语法只能在node环境中运行,直接在浏览器中使用会报错。
什么是模块化?
在讲模块化之前,我们先复习一下less,我们在a.less文件中定义了一个颜色变量@white:#fff,现在我在b.less中想用到这个@white变量应该怎么办呢?使用@import 'a'就可以了。在上面那段less代码中,其实我们就用到了模块化编程,只不过是基于less的。现在我们再来看一下js如何实现模块化编程。
传统的写法比较简单,就是把自己需要的js文件全部放到index,html中引入,在引入的时候还需要确保引入的顺序是正常的,本质上来说,就是把所有代码全部引入到一个js文件中。而现在我们采用模块化的写法,就会相对来说结构清晰一点,比如在main.js里面需要使用jquery,那么我们可以在main.js里面这么写:import $ from "jquery",在index.html里面只需要引入main.js即可,采用这种写法可以让文件间的依赖关系更加清楚,实现按需加载,同时结构也会更加合理。
JS的模块规范有哪些
在es6之前,主要采用AMD和CMD这2中规范,AMD规范比较好的一个实现库是require.js,CMD对应的是seajs,还有一点node.js也是符合CMD规范的,所以cmd规范的代码可以直接在node环境下运行。而js的最新版本es6则提供了原生的module语法,以实现对模块化的支持
CMD语法:
// 定义模块
module.exports =function(){
vargreet =document.createElement('div');
greet.textContent ="Hi there and greetings!";returngreet;};
//引用模块
letgreeter =require('./Greeter.js');
ES6语法:
//定义模块
etdog="我爱哈士奇"
exportdefaultdog
//引用模块
importdogfrom'animal'
webpack干了什么
上面已经提到这些模块化的语法是不能在浏览器环境中运行的,所以我们需要这些将这些互相依赖的文件进行编译(打包),编译成浏览器能够运行的代码。而webpack做的就是这个打包操作,比如我们在main.js里面依赖了add.js文件,而add.js文件使用import $ form 'jquery'
,那么webpack会发现main.js需要add.js,然后将add.js导入,导入add.js的时候发现add.js需要jquery,然后又将jquery给导入,最后生成了一个总的js文件,这样我们的代码就可以到浏览器环境上运行了。
webpack与es6
es6提供了很多激动人心的新特性,但是这些新特性并不被所有的浏览器支持,为了使用这些新特性,我们可以使用babel插件,将我们的代码es6代码转换成es5代码。但是对于一些es6新的api,比如promise等,需要使用babel-polyfill,而如何使用babel-polyfill呢?只要在需要对es6转换成es5的文件头部加上import 'babel-polyfill';
很明显,这是es6的模块语法,表示这个文件依赖babel-profill这个文件,所以我们需要使用打包工具来进行打包,这样才能运行这段代码。所以,想要学习es6,webpack是必须要迈过去的一道坎。
如何学习webpack
谈了这么多,总算要到如何学习了。学习资料的话,可以去看一些已经整理好的资料或者官网的文档,了解config的基本语法就可以开始撸了。这里推荐一个练手的项目:多动症简历。这是一个很有意思的项目,里面用到了es6+promise+webpack,如果你能将这段代码进行打包,并实现以下几个要求,那么你webpack可以说是入门了。如果你对这个多动症简历项目感兴趣,可以去看一下项目作者的这篇文章:用原生js写一个"多动症"的简历,推荐直接阅读项目的源代码,从中可以学到很多知识。
- 使用babel-loader将es6转换成es5
- 将css单独的打包成一个文件
- 压缩js代码
- 压缩css代码
- 使用html模板生成index.html
至于上面这些功能如何实现,需要用到哪些插件,希望你能自己去百度,去google,去stackoverflow。只有自己练过,才算彻底掌握,如果只是简单的跟着官网项目做几个简单的demo,其实没什么意义。
踩坑记录
这是我在使用webpack时遇到的一些坑,webpack的版本号是3.0,如果你也遇到了,可以参考一下下面的解决方案。
使用extract-text-webpack-plugin
生成单独的css时,可能会报错chunk.sortModules is not a function
,解决方案是回退extract-text-webpack-plugin版本号到2.1.2,npm i extract-text-webpack-plugin@2.1.2
。
一般的压缩js插件无法压缩es6,如果想对es6代码进行压缩,可以使用UglifyjsWebpackPlugin。但是如果教程一步一步来还是会报错Unexpected token: name (doc)
。解决方案是将babel配置拿出来,不要放在webpack.config中,单独的放到.babelrc中。
使用了extract-text-webpack-plugin
后无法进行css压缩?
可以使用optimize-css-assets-webpack-plugin这一插件来解决。
webpack和gulp有什么区别
两者虽然在某些功能上类似,比如都可以压缩代码,编译less等。但是两者的定位不同,刚才也提到过了,webpack本质上是一个打包工具,支持CMD的语法,将多个互相依赖的js文件打包成一个js文件。而gulp则是一个自动化工具,用来处理less编译,代码压缩这些,gulp的核心概念是管道,所有文件在管道中流通,然后在流的过程中依次进行代码压缩,less编译等操作,最后再将这些文件流输出到指定目录。所以两者在功能以及定位上都有很大的不同。