webpack 从入门到放弃

随着前端项目复杂程度愈来愈高,依赖也愈来愈多,为了提升项目中代码的可复用性,前端开始提出模块化开发的思路,前端模块化会有如下几个痛点:javascript

命名冲突
文件依赖
代码复用

模块化,会将相关的代码封装成一个package包的文件,当须要的时候,直接拿来用便可(import引入)。至于相关文件的直接依赖如何处理,webpack会帮咱们解决这个问题。那么模块化应该使用什么样的规范呢?常见的模块化的标准主要以下:php

commonjscss

nodejs使用的就是commonJs的规范,采用的同步方式加载依赖,一个文件就是一个模块。html

导入导出方式以下:前端

导入:const aa = require('./aa') 导出:module.exports = aa.fun

缺点是加载的模块是同步的,只有加载完才能执行后面的操做。由于 node.js 的模块文件通常存在于本地硬盘,因此通常不会出现这个问题,可是在浏览器环境该规范就不那么适用了。java

AMDnode

由于commonJS不适用于浏览器的环境,因此出现AMD规范。特色: 异步加载/推崇依赖前置、提早执行 。require.js最佳实践react

使用方式:webpack

定义模块: define()
加载模块:require() 引用:require.config()
CMD

CMD的使用方式如上,可是特色不太同样。CMD是异步加载/依赖就近、延迟执行 sea.js最佳实践nginx

ES6

ES6 直接在语言层面上实现了模块化。咱们如今用的最多的就是 ES6 模块化的实践方式。

导入导出方式以下:

导入:
import aa from 'aa' import {A} from 'aa' 导出: export default {A, B} export {A, B} export funtion aa() {}

虽然ES6是模块化的最终方案,可是仍是在许多浏览器上有兼容问题,须要对代码进行转码处理才行。

样式文件中的模块化

前端开发中,样式文件也开始支持模块化,以stylus为例,一般将一些通用的文件放到文件中,在使用相关的样式时,直接@import引入文件,就能使用对应的代码片断,固然也能定义一些全局的参数(颜色,圆角类)进行使用。

// common.styl .center-transform top 50% left 50% transform translate(-50% -50%) center-transform() top 50% left 50% transform translate(-50% -50%) // 使用 @import 'common.styl' .box { center-transform }

 

webpack和Gulp/Grunt、Rollup比较

Grunt: 是一套前端自动化工具,帮助处理反复重复的任务。通常用于:编译,压缩,合并文件,简单语法检查等
Gulp: 是基于“流”的自动化构建工具,采用代码优于配置的策略,更易于学习和使用
Rollup: Rollup 是一个和 Webpack 很相似但专一于 ES6 的模块打包工具。 Rollup 的亮点在于能针对 ES6 源码进行 Tree Shaking 以去除那些已被定义但没被使用的代码,以及 Scope Hoisting 以减少输出文件大小提高运行性能。 可是Rollup 生态链还不完善,体验不如 Webpack。
webpack: Webpack 是模块化管理工具和打包工具。经过 loader 的转换,任何形式的资源均可以视做模块,好比 CommonJs 模块、AMD 模块、ES6 模块、css、图片等。它能够将许多松散的模块按照依赖和规则打包成符合生产环境部署的前端资源。还能够将按需加载的模块进行代码分隔,等到实际须要的时候再异步加载

 

开始使用webpack

首先建立一下的目录结构:

.
├── src
│   ├── assemble
│   │   ├── css
│   │   │   ├── index.css
│   │   ├── index.html
│   │   └── js
│   │       ├── index.js
│   │       └── test.js
│   ├── babyTest
│   │   ├── css
│   │   │   └── index.css
│   │   ├── index.html
│   │   └── js
│   │       └── index.js


文件内容:
// 1. assemble-index.html: <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title></title> </head> <body> </body> </html> // 2. assemble-css/index.css: body {background: red} // 3. assemble-js/index.js: import '../css/index.css' console.log('index.js') // 4. assemble-js/test.js: console.log('test.js') babyTest目录和上面相似
建立package.json文件: npm init
安装webpack(全局、目录安装):npm install webpack -D

建立webpack.config.js文件,下面直接配置的是多文件入口:

// 引入插件 const HtmlWebpackPlugin = require('html-webpack-plugin') // 相关配置 module.exports = { mode: 'development', // 指定webpack的模式 entry: { 'assemble/js/index': './src/assemble/js/index.js', 'assemble/js/test': './src/assemble/js/test.js', 'babyTest/js/index': './src/babyTest/js/index.js' }, output: { filename: '[name].js', // 打包后输出文件的文件名 path: path.resolve('./output/market') // 打包后的文件存放的地方 }, module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'] } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/assemble/index.html', filename: 'assemble/index.html', chunks: ['assemble/js/index'] }), new HtmlWebpackPlugin({ template: './src/babyTest/index.html', filename: 'babyTest/index.html', hash: true, chunks: ['babyTest/js/index'] }) ] }

上面写的实例中,将loader和plugins已经使用了,能够先按照上面的使用,后边将进行详细方法的介绍。

使用前,安装对应的依赖包

npm install css-loader style-loader html-webpack-plugin -D
终端执行打包命令: webpack

能够看到在根目录下有output目录,里面就行对应的打包文件。直接运行output文件下的目录,可以看到对应效果,css和js都可以执行成功。

备注:执行打包命令的方式有如下几种方式

node_modules/.bin/webpack
webpack在package.json文件中配置对应的命令 "scripts": { "start": "webpack"}

entry

入口起点(entry point)指示 webpack 应该使用哪一个模块,来做为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。

每一个依赖项随即被处理,最后输出到称之为 bundles 的文件中,,entry属性 来指定一个入口起点(或多个入口起点)。默认值为 ./src。

output

output 属性告诉 webpack 在哪里输出它所建立的 bundles,以及如何命名这些文件,默认值为 ./dist。基本上,整个应用程序结构,都会被编译到你指定的输出路径的文件夹中。  

Loader

loader 用于对模块的源代码进行转换。loader 可使你在 import 或"加载"模块时预处理文件。所以,loader 相似于其余构建工具中“任务(task)”,并提供了处理前端构建步骤的强大方法。loader 能够将文件从不一样的语言(如 TypeScript)转换为 JavaScript,或将内联图像转换为 data URL。loader 甚至容许你直接在 JavaScript 模块中 import CSS文件!

上面的配置中就用到了 css-loader和style-loader,主要是在对引用的css文件会用style-loader和css-loader进行处理,当配置多个loader的时候,按照从左至右的方式进行处理。

Loaders的配置主要包含如下配置:

test(必填): 用正则匹配对应文件的扩展名
use(必填):loader的名称
include/exclude(非必填):手动添加必须处理或者是忽略的文件
query(非必填):为loaders提供额外的设置选项

在webpack中使用的方式

命令行调用:webpack --module-bind jade --module-bind 'css=style!css'
经过require:require('style-loader!css-loader?minimize!./main.css')
使用配置文件: 如上配置

联系紧密的Babel

Babel是一个编译JavaScript的平台,能够帮咱们将编译的代码

让你能使用最新的JavaScript代码(ES6,ES7...),而不用管新标准是否被当前使用的浏览器彻底支持
让你能使用基于JavaScript进行了拓展的语言

Babel的安装与使用

Babel的安装

Babel实际上是几个模块化的包,其核心功能称为babel-core的npm包中,webpack能够把其不一样的包整合在一块儿使用,对于每个你须要的功能或拓展,你都须要安装单独的包(用的最多的就是解析ES6语法的包 babel-preset-env)
npm install --save-dev babel-core babel-loader babel-preset-env

在webpack.config.js中,module的rules中添加;

{
  test: /\.js$/, use: { loader: 'babel-loader', options: { presets: [ 'env', 'react' ] } }, include: /src/, exclude: /node_modules/ }
Babel的配置

Babel的配置能够直接在webpack.config.js中进行配置,可是有时配置项过多,但在这个文件中配置过多js编译规则的代码,显得可读性不太好,所以支持在.babelrc中单独配置,webpack会自动调用这个文件中的配置项。

// .babelrc文件 { "presets": ["react", "env"] }

loader的特性(引用官网)

loader 支持链式传递。可以对资源使用流水线(pipeline)。一组链式的 loader 将按照相反的顺序执行。loader 链中的第一个 loader 返回值给下一个 loader。在最后一个 loader,返回 webpack 所预期的 JavaScript。
loader 能够是同步的,也能够是异步的。
loader 运行在 Node.js 中,而且可以执行任何可能的操做。
loader 接收查询参数。用于对 loader 传递配置。
loader 也可以使用 options 对象进行配置。
除了使用 package.json 常见的 main 属性,还能够将普通的 npm 模块导出为 loader,作法是在 package.json 里定义一个 loader 字段。
插件(plugin)能够为 loader 带来更多特性。
loader 可以产生额外的任意文件。

 

扩展-常使用的loader清单

loader name 介绍
css-loader 解析@import 和 Url()引用的css文件,转化成 import/require() 的方式而后在解析他们
style-loader 将 CSS 放在 <style></style> 标签中注入到 DOM 中
sass-loader 将 SASS/SCSS 转换为 css
less-loader 将 less 转化为 css
html-loader 将 html 输出为字符串,也能够根据配置进行压缩
babel-loader 加载 ES2015+ 代码,而后使用 Babel 转译为 ES5
url-loader 将文件加载为 Base64 编码的 URL
file-loader 能够解析项目中的url引入(不只限于css),根据咱们的配置



plugin

插件是 webpack 的支柱功能。webpack 自身也是构建于,你在 webpack 配置中用到的相同的插件系统之上!

插件目的在于解决 loader 没法实现的其余事。

Plugins在构建的过程当中,经过在构建流程中注入对应的钩子,给webpack带来很大的灵活性。

Loaders和Plugins经常被弄混,可是他们实际上是彻底不一样的东西,能够这么来讲,loaders是在打包构建过程当中用来处理源文件的(JSX,Scss,Less..),一次处理一个,Plugins并不直接操做单个文件,它直接对整个构建过程其做用

上面的实例中就使用了html-webpack-plugin插件,主要的功能就是自动引用使用的js文件,使用css的话,也会根据必定规则进行动态插入,在控制台查看文件代码时,能够看到引用的css文件,会自动插在<head></head>之间。如截图所示

咱们能够根据本身的项目构建方式,使用对应的插件,就不一一举例说明了。

扩展-经常使用的Plugins清单

Plugins name 介绍
HtmlWebpackPlugin 简单建立 HTML 文件,用于服务器访问
clean-webpack-plugin 删除指定的文件夹
webpack-bundle-analyzer webpack打包体积查看,便于优化文件体积
speed-measure-webpack-plugin 查看测量出在你的构建过程当中,每个 Loader 和 Plugin 的执行时长(优化webpack时能帮你看出对应的时间)



启动静态服务器

启动一个静态服务器,默认会自动刷新,就是说你对html,css,js文件作了修改并保存后,浏览器会默认刷新一次展示修改后的效果

正常状况下咱们都是在开发环境中开发项目,因此以前配置的脚本"dev"能够派上用场了,在执行npm run dev命令后,会启动静态服务器,咱们访问localhost:3000端口就能够看到开发的页面内容了

对应的配置文件:

// webpack.config.js的配置文件 devServer: { host: 'localhost', // 默认是localhost port: '3000', // 端口 open: true, // 自动打开 hot: true, // 开启热更新 openPage: 'assemble' // 默认打开的文件 } // package.json中的配置 "scripts": { "dev": "webpack-dev-server --open" }

 

开发、测试、上线构建的细微区别

一般本地开发,测试和线上的构建方式略微有点区别,线上文件都会将文件中的空行,空格,换行清除,而且压缩html,css,js和对应image的体积,这样就能保证体积最小,加快页面的加载速度。

可是开发和测试环境一般,在浏览器中,没法对代码逐行打断点进行调试,全部须要使用source maps进行调试,它使得咱们在浏览器中能够看到源代码,进而逐行打断点调试。

使用source maps方法

在webpack.config.js文件中,添加devtool属性,赋值为 source-map或者inline-source-map便可,后者报错信息更加具体,会指示源代码中的具体错误位置,而source-map选项没法指示到源代码中的具体位置。

广州品牌设计公司https://www.houdianzi.com PPT模板下载大全https://redbox.wode007.com

webpack优化

1. 代码编写过程当中遇到的现象

问题描述:更改一个文件,致使全部的文件都会从新进行编译。

修改前:
修改后:

优化方案:使用缓存

安装cache-loader模块 npm install cache-loader -D
在module.rules对应的loader最前面添加cache-loader
相关文章
相关标签/搜索