郑州做网站推,华为官网手机商城,湖北网站建设服务公司,防止网站流量被刷前端技术发展迅猛#xff0c;各种可以提高开发效率的新思想和框架层出不穷#xff0c;但是它们都有一个共同点#xff0c;即源代码无法直接运行#xff0c;必须通过转换后才可以正常运行。webpack是目前主流的打包模块化JavaScript的工具之一。
本章主要涉及的知识点有各种可以提高开发效率的新思想和框架层出不穷但是它们都有一个共同点即源代码无法直接运行必须通过转换后才可以正常运行。webpack是目前主流的打包模块化JavaScript的工具之一。
本章主要涉及的知识点有
l 什么是webpack
l webpack的作用
l webpack的配置
l webpack-dev-server 8.1 什么是webpack 以前一个网站可能只是由几个HTML和CSS文件构成在某些情况下可能还有一个或几个JavaScript文件。但随着前端技术的发展这一切都被改变。
整个开发社区一直致力于改善用户和开发人员在使用和构建JavaScript/Web应用程序方面的整体体验。因此在项目中引入了许多新的库和框架。
一些设计模式也随着时间的推移而演变为开发人员提供了一种更好、更强大但非常简单的编写复杂JavaScript应用程序的方法。网站不再只是一个包含几个文件的程序包随着JavaScript模块的引入编写封装的小块代码成为一种新趋势。但随之而来的是网站代码的体积越来越大而且JavaScript版本不断升级新的API层出不穷在开发人员编写的代码类型和浏览器能够理解的代码类型方面也存在巨大差异。开发人员必须使用大量被称为polyfills的辅助代码以确保浏览器能够解析其中的代码。
为了解决这些问题开发了一系列构建工具它们各有优缺点。由于前端工程师很熟悉JavaScriptNode.js又可以满足所有构建需求因此大多数构建工具都是用Node.js开发的。
1. Grunt
Grunt是一个任务执行者它有大量现成的插件封装了常见的任务也能管理任务之间的依赖关系自动化地执行依赖的任务。每个任务的具体执行代码和依赖关系写在配置文件Gruntfile.js里代码如下
module.exports function(grunt) {grunt.initConfig({uglify: {app_task: {files: {build/app.min.js: [lib/index.js, lib/test.js]}}}, watch: {another: {files: [lib/*.js],}}});grunt.loadNpmTasks(grunt-contrib-uglify);grunt.loadNpmTasks(grunt-contrib-watch);grunt.registerTask(dev, [uglify,watch]);
};其中uglify和watch都是插件分别用于压缩和监听自动刷新grunt.loadNpmTasks用于加载插件grunt.registerTask用于执行任务。在项目根目录下执行命令grunt dev就会启动JavaScript文件压缩和自动刷新功能。
Grunt的优点是灵活它可以执行自定义的任务并且有大量的可复用的插件封装好了常见的构建任务。
Grunt的缺点是集成度不高要写很多配置后才可以用无法做到开箱即用。
2. Gulp
Gulp是一个基于流的自动化构建工具除了可以管理和执行任务之外还支持监听文件、读写文件。Gulp被设计得非常简单只通过5种方法就可以支持几乎所有的构建场景gulp.task用于注册一个任务gulp.run用于执行任务gulp.watch用于监听文件的变化gulp.src用于读取文件gulp.dest用于写文件。
Gulp的最大特点是引入了流的概念同时提供了一系列常用的插件去处理流流可以在插件之间传递。Gulp的示例代码如下
01 var gulp require(gulp);
02 var jshint require(gulp-jshint);
03 var sass require(gulp-sass);
04 var concat require(gulp-concat);
05 var uglify require(gulp-uglify);
06 gulp.task(sass, function() {
07 gulp.src(./scss/*.scss)
08 .pipe(sass())
09 .pipe(gulp.dest(./css));
10 });
11 gulp.task(scripts, function() {
12 gulp.src(./js/*.js)
13 .pipe(concat(all.js))
14 .pipe(uglify())
15 .pipe(gulp.dest(./dist));
16 });
17 gulp.task(watch, function(){
18 gulp.watch(./scss/*.scss, [sass]);
19 gulp.watch(./js/*.js, [scripts]);
20 });代码解析
第0105行引入Gulp和相关插件。第0610行通过gulp.task(sass, function() {}编译SCSS任务。其中第07行通过gulp.src读取文件第08行通过pipe管道加载插件第09行输出CSS文件。第1116行通过gulp.task(scripts, function() {}合并压缩JavaScript文件。第1720行通过gulp.task(watch, function() {}监听文件的变化。
Gulp的优点是好用又不失灵活既可以单独完成构建也可以和其他工具搭配使用。其缺点和Grunt类似集成度不高要写很多配置后才可以用无法做到开箱即用。
可以将Gulp看作Grunt的加强版。相对于GruntGulp增加了监听文件、读写文件、流式处理的功能。
3. webpack
webpack是一个打包模块化JavaScript的工具在webpack里一切文件皆模块通过Loader转换文件通过Plugin注入钩子最后输出由多个模块组合成的文件。webpack专注于构建模块化项目。
webpack具有很大的灵活性通常在项目中编写webpack.config.js配置处理文件的方式示例代码如下
module.exports {entry: ./app.js,output: {filename: bundle.js}
}其中entry是所有模块的入口webpack从入口开始递归解析出所有依赖的模块output将入口所依赖的所有模块打包成一个bundle.js文件并输出。
webpack专注于处理模块化的项目。通过webpack现在使用React、Vue、Angular等搭建的项目能做到开箱即用、一步到位并且可以通过Plugin扩展很多功能。webpack社区庞大而活跃经常引入紧跟时代发展的新特性能为大多数场景找到已有的开源扩展。 8.2 webpack的作用 简单来说webpack会遍历项目中的所有文件如JavaScript、CSS、SCSS、图片、模板等并创建它们的依赖关系图该依赖关系图用于描述各个模块之间的依赖关系。根据依赖关系图对项目中的各模块进行组合和打包形成一个bundle.js文件在这个文件中可以很容易地插入HTML文件并用于应用程序。
webpack在打包的同时还会对各文件进行编译。把浏览器不能识别的语法例如ES 6的语法、Node.js的模块化、Sass编译成CSS将TypeScript编译成JavaScript等转换成浏览器能够识别的语法。
webpack在打包时可以根据配置对代码进行压缩、优化以减小网络传输过程中文件的体积。最典型的做法是把所有变量名都精简为一个字母所有的换行符和缩进都去掉。如图8.1所示是webpack打包后的JS文件。 webpack的功能还有很多例如代码分割、自动刷新等。代码分割就是提取多个页面的公共代码、提取首屏不需要执行部分的代码让其异步加载。自动刷新是指监听本地源代码的变化自动重新构建、刷新浏览器。
webpack官方网站首页中的一张图片形象地展示了webpack的作用如图8.2所示。 目前随着单页应用的流行大多数团队在开发新项目时会采用“模块化新语言新框架的方式。webpack可以为这些模块化项目提供一站式的解决方案、良好的生态链和维护团队从而提供良好的开发体验并保证项目质量。 8.3 webpack的配置 webpack的配置项很多具体可以参考官方网站文档https://webpack.js.org/concepts/。本节介绍几个重要且常用的配置项。
在对webpack进行配置之前首先要安装webpack。在终端输入如下代码
npm install webpack webpack-cli --save-dev
webpack-cli是一个用来在命令行中运行webpack的工具可以用来处理命令行参数。
通常在项目根目录下增加webpack.config.js文件在该文件中编写代码进行webpack的配置。例如在webpack.config.js文件中添加以下代码
01 const path require(path);
02 const HtmlWebpackPlugin require(html-webpack-plugin);
03
04 module.exports {
05 entry:./src/index.js,
06 output:{
07 path: path.join(__dirname, /dist),
08 filename: bundle.js
09 },
10 module: {
11 rules: [
12 {
13 test: /\.(js|jsx)$/,
14 exclude: /node_modules/,
15 use: {
16 loader: babel-loader
17 }
18 }
19 ]
20 },
21 plugins: [
22 new HtmlWebpackPlugin({
23 template: ./src/index.html
24 })
25 ]
26 }代码解析
第01行引入Node.js内置模块path用于获取文件路径并更改文件的位置。第02行引入插件html-webpack-plugin用于生成一个HTML文件这个HTML文件用于引用打包后的JavaScript文件。因为JavaScript文件必须放到HTML文件中才可以在浏览器中执行。从第04行开始定义module.exports对象其中包含一些属性例如entry、output、module、plugins等。第05行的entry属性用于指定webpack应该从哪个文件开始以便创建内部依赖关系图。这里是src下的index.js文件。第06行的output属性指定应该在哪里生成打包后的文件以及打包后的文件的名称。output.path用于指定文件存储位置output.filename用于指定文件名称。第1020行的module指定需要哪些loader。loader指定webpack应该怎样处理特定类型的文件。注意webpack默认只理解JavaScript和JSON类型的文件对于项目中使用的其他类型文件或语言例如PNG、JPG、GIF格式的图片文件或者SCSS、LESS文件需要在这里加载相应的loader插件进行处理。此处用正则表达式匹配所有后缀是.js或.jsx的文件且排除/node_modules/下的文件使用babel-loader对这些文件进行编译处理。还有很多别的loader插件例如处理CSS和SCSS文件的style-loader、css-loader、sass-loader处理图片的url-loader等。第2125行的plugins是插件属性用于扩展webpack的功能。这里使用html-webpack-plugin插件将src/index.html作为模板文件所有打包后的文件都将自动放入该HTML文件中。html-webpack-plugin插件还有更多的配置具体可以参考官方文档。插件还有mini-css-extract-plugin用于将CSS提取到单独的文件中即为每个包含CSS的JavaScript文件创建一个CSS文件terser-webpack-plugin用于压缩JavaScript文件。
最后要处理ES 6代码。ES 6是2015年发布的JavaScript语言标准它引入了新的语法和API例如class、let、for...of、promise等但是这些JavaScript新特性只被最新版本的浏览器支持。低版本浏览器并不支持。因此低版本浏览器需要一个转换工具把ES 6代码转换成浏览器能识别的代码。Babel就是这样的一个工具它是JavaScript语法的编译器。
Babel工具在使用之前需要先进行配置。
首先在项目根目录下创建一个.babelrc文件它是一个JSON格式的文件用来保存Babel工具的配置。webpack中的babel-loader加载后会从项目根目录下的.babelrc文件中读取配置。
在.babelrc配置文件中主要是对预设presets和插件plugins进行配置。.babelrc配置文件一般如下
{presets: [es2015,react]
}其中presets属性告诉Babel要转换的源代码使用了哪些新的语法特性它是一组Plugins的集合。上面的代码表示先用React转换然后用ES 2015ES 6转换。
以上配置中用到的loader或plugins如果不是webpack内置的那么在使用前需要先安装例如编译CSS和SCSS文件的loader使用npm install css-loader style-loader sass-loader --save-dev进行安装。
webpack配置好以后可以在package.json文件中增加如下代码 scripts: {dev: webpack --config webpack.config.js
},在scripts属性中npm允许通过名称引用本地安装的Node.js包。上面的代码表示在开发dev模式下运行webpack在终端命令行中输入npm run dev时执行webpack --config webpack.config.js。 在实际项目中需要根据特定情况使用不同的配置文件例如开发时执行webpack.dev.config.js当需要打包部署到生产环境时执行webpack.prod.config.js。这些webpack文件的配置项也要根据用途进行不同的配置例如开发环境时需要配置webpack-dev-server但是生产环境时需要配置CSS、JS压缩等。 8.4 webpack-dev-server 到目前为止每次进行更改都需要重新构建代码。对于开发中频繁修改代码并且要即时查看页面情况来说这是非常麻烦且影响开发效率的。 webpack提供了一个实时重新加载的Web服务器——webpack-dev-server它可以自动构建和刷新页面。可以在终端输入下面的代码安装 npm install webpack-dev-server --save-dev 安装后需要更新package.json中script的dev代码如下 dev: webpack serve --mode development 在webpack.config.js中增加以下代码 devServer: {hot: true,port: 8080,compress: true,headers: {Access-Control-Allow-Origin: *},proxy: {/api: {target: http://localhost:3000,pathRewrite: { ^/api: },},}
}代码解析 Hottrue表示启用模块热替换该功能会在应用程序运行过程中替换、添加或删除模块而无需重新加载整个页面可以加快开发速度。port指定监听请求的端口号。compresstrue表示启用gzip压缩。headers表示为所有响应添加headers。Access-Control-Allow-Origin*表示允许所有域名跨域访问。proxy用来设置代理。上面的代码中假如有接口/api/users它实际上会将请求代理到http://localhost:3000/users。 pathRewrite表示将接口中的/api替换为空。 本节选自《React.jsNode.jsMongoDB企业级全栈开发实践》获出版社和作者授权共享。