webpack总结

一、Webpack 是什么?

webpack是一款模块加载器兼打包工具,它能把各种资源,例如JS(含JSX)、coffee、样式(含less/sass)、图片等都作为模块来使用和处理。 简单说就是模块加载器,通过使用Webpack,能够像Node.js一样处理依赖关系,然后解析出模块之间的依赖,将代码打包。

二、为什么需要打包?

  • 像sass,JSX等代码虽然极大的提高了开发效率,但是本身并不被浏览器所识别,需要我们对其进行编译和打包,变成浏览器识别的代码
  • 模块化(让我们可以把复杂的代码细化为小的文件)
  • 优化加载速度(压缩和合并代码来提高加载速度,压缩可以减少文件体积,代码合并可以减少http请求)
  • 使用新的开发模式

三、webpack主要特性

  • 同时支持CommonJS和AMD模块(对于新项目,推荐直接使用CommonJS);
  • 串联式模块加载器以及插件机制,让其具有更好的灵活性和扩展性,例如提供对CoffeeScript、ES6的支持;
  • 可以基于配置或者智能分析打包成多个文件,实现公共模块或者按需加载;
  • 支持对CSS,图片等资源进行打包,从而无需借助Grunt或Gulp(browserify只能打包JS文件);
  • 开发时在内存中完成打包,性能更快,完全可以支持开发过程的实时打包需求;
  • source map有很好的支持。

四、配置(webpack.config.js文件)

var webpack = require(‘webpack‘);var path = require(‘path‘);var SpritesmithPlugin = require(‘webpack-spritesmith‘);module.exports = {    // context: __dirname + ‘\\app‘, //上下文    entry: path.resolve(__dirname, ‘app/index.js‘), //入口文件    output: { //输出文件        path: path.resolve(__dirname, ‘app/build/script‘),        filename: ‘bundle.js‘    },    module: {        loaders: [ //加载器            {test: /\.html$/, loader: ‘raw‘},            // {test: /\.css$/, loader: ‘style!css!postcss‘},            {test: /\.css$/, loader: ‘style!css‘},            // {test: /\.(png|jpg|ttf)$/, loader: ‘url?limit=8192‘}            {test: /\.(png|jpg|ttf)$/, loader: ‘file!url?limit=8192‘}        ]    },    // postcss: function () {    // return [autoprefixer];    // },    plugins: [ //插件        new webpack.BannerPlugin(‘This file is created by shiddong.‘),        new SpritesmithPlugin({            src: {                cwd: path.resolve(__dirname, ‘app/images/‘),                glob: ‘*.png‘            },            target: {               image: path.resolve(__dirname, ‘app/build/images/sprite.png‘),               css: path.resolve(__dirname, ‘app/build/css/sprite.css‘) //产生的样式文件,图片的样式类名是 icon-图片名            },           apiOptions: {               cssImageRef: ‘../images/sprite.png‘           },           spritesmithOptions: {               algorithm: ‘top-down‘           }       })    ]};

五、webpack.config.js 配置详解

(1)entry

入口文件,可以传字符串,那说明入口文件只有一个;也可以传数组或对象,指定多个入口文件。

有两种语法:

<1> 先require path,再利用reslove方法对路径进行解析。

var path = require(‘path‘);entry: path.resolve(__dirname, ‘app/index.js‘), //入口文件

<2> 先定义好上下文路径,那么entry中的路径直接在这个路径下开始

context: __dirname + ‘\\app‘, //上下文entry: ‘./index.js‘, //入口文件

注:webpack中引入的path是nodejs内置的package,用来处理路径 —— 参考菜鸟教程node.js工具模块。

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

entry: [    ‘webpack/hot/only-dev-server‘,    ‘./js/app.js‘]

当entry是个对象的时候,我们可以将不同的文件构建成不同的文件,按需使用。每一个键值对,就是一个入口文件。

备注:当然也有其他的办法,如express框架,在index.html同路径建立一个server.js,然后运行 node server.js即可。

// express 是一个基于Node.js 平台的web应用开发框架 —— 快速、极简、开放var port = 8000,express = require(‘express‘),app = express();app.use(‘/‘, express.static(__dirname));app.listen(port);console.log(‘Now serving http://localhost:‘ + port + ‘/index.html‘);

(2)output

生成打包文件的配置,可以指定path(路径),当有多个入口文件时,还可以使用[name]、[hash]、[chunkhash]等值,来对应替换为入口的文件的配置。

output: { //输出构建后的文件    path: path.resolve(__dirname, ‘app/build/script‘),    filename: ‘bundle.js‘}

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

entry: {    index: ‘index.js‘},output: {    path: ‘./js‘,    filename: ‘[name].bundle.js‘ // [name] 会由entry中的键(这里是index)替换}

(3)module

定义了对模块的处理逻辑,在webpack中,所有的资源都被当做模块。对于不同文件类型的资源,都有对应的loader。
模块的加载相关配置定义在module.loaders中。

loaders: 加载器配置,通过正则表达式去匹配不同后缀的文件名,然后给它们定义不同的加载器。它可以转换项目中的资源文件,比如说给css文件定义串联的两个加载器(!用来定义级联关系),顺序是从右向左使用:

module: {    loaders: [        { test: /\.js?$/, loaders: [‘react-hot‘, ‘babel‘], exclude: /node_modules/ },        { test: /\.js$/, exclude: /node_modules/, loader: ‘babel-loader‘},        { test: /\.css$/, loader: "style!css" },        { test: /\.less/, loader: ‘style-loader!css-loader!less-loader‘}    ]}

其中,exclude: /node_modules/,
exclude,include手动添加屏蔽不需要处理的文件(文件夹)或必须处理的文件(文件夹)

比较常用的loader:

css-loader: 将样式打包成字符串。
style-loader:将样式字符串添加到页面的style标签中

还可以添加用来定义png、jpg这样的图片资源在大于8k时正常打包,小于8k时自动处理为base64图片的加载器:

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

其中,? 表示加载器支持通过查询字符串的方式接受参数。

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

require(‘./bootstrap.css‘);require(‘./myapp.less‘);var img = document.createElement(‘img‘);img.src = require(‘./glyph.png‘);

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

(4)plugins

插件,它可以干很多很多的事情,非常强大,官方提供了很多插件,第三方也可以写插件。对于用到的插件,只需要将插件new出来放到数组中即可。

<1> BannerPlugin 内置插件来实践插件的配置和运行,这个插件的作用是给输出的文件头部添加注释信息。
<2> ProvidePlugin 插件的作用是自动加载jquery模块,也就是说将jquery变成了全局的模块,当然我们需要在index.html中使用script标签导入。

[原因:由于jquery没有模块化的概念,也没有适配webpack,所以我们使用jquery时,需要在index.html中导入,然后使用 ProvidePlugin 插件使其自动加载。]

plugins: [    new webpack.BannerPlugin(‘This file is created by shiddong.‘),    // 此插件会自动加载jquery,解决jquery无法引用的问题    new webpack.ProvidePlugin({        $: "jquery",        jQuery: "jquery",        window.jQuery: "jquery"    })]

(5)导入使用

只需要在index.html中导入bundle.js,<script src="bundle.js">script>,不需要在index.html中导入js文件了,只需要使用 require 导入模块就行,webpack会自己解决它们之间的依赖。

<1> 依赖第三方库可以将其下载到node-modules中,然后导入相应的模块:

//require(‘angular‘)导入的是 node_modules 中的angular模块require("angular"); //var angular = require(‘angular‘);require("bootstrap");var demoApp = angular.module(‘demoApp‘, []);

<2> 或者类似于导入本地的js文件,可以建立一个 common.js 文件,然后导入 angular 和 bootstrap。然后在使用的时候直接require(‘./common‘)

(6)处理图片

loaders: [    {      test: /\.(png|jpg)$/,      loader: ‘url-loader?limit=8192‘    }  ]

其中,

<1> test 属性代表可以匹配的图片类型,除了 png、jpg 之外也可以添加 gif 等,以竖线隔开即开。
<2> loader 后面 limit 字段代表图片打包限制,这个限制并不是说超过了就不能打包,而是指当图片大小小于限制时会自动转成 base64 码引用。上例中大于8192字节的图片正常打包,小于8192字节的图片以 base64 的方式引用。

//Option 1,使用 ?{ test: /\.png$/,   loader: ‘url-loader?limit=1024‘}//Option 2,使用query属性{ test: /\.png$/,  loader: ‘url-loader‘,  query: {limit=1024}}

<3> url-loader 后面除了 limit 字段,还可以通过 name 字段来指定图片打包的目录与文件名:

loaders: [    {      test: /\.(png|jpg)$/,      loader: ‘url-loader?limit=8192&name=images/[hash:8].[name].[ext]‘    }  ]

name 字段指定了在打包根目录(output.path)下生成名为 images 的文件夹,并在原图片名前加上8位 hash 值。

(7)生成雪碧图

var path = require(‘path‘);var SpritesmithPlugin = require(‘webpack-spritesmith‘); //安装雪碧图依赖模块:webpack-spritesmithmodule.exports = {    entry: path.resolve(__dirname, ‘app/main.js‘),    output: {        path: path.resolve(__dirname, ‘build‘),        filename: ‘bundle.js‘    },    plugins: [        new SpritesmithPlugin({            src: {                cwd: path.resolve(__dirname, ‘app/images/‘),                glob: ‘*.png‘            },            target: {                image: path.resolve(__dirname, ‘build/images/sprite.png‘),                css: path.resolve(__dirname, ‘build/css/sprite.css‘) //产生的样式文件,图片的样式类名是 icon-图片名            },            apiOptions: {                cssImageRef: ‘../images/sprite.png‘            },            spritesmithOptions: {                algorithm: ‘top-down‘            }        })    ]};

链接:https://zhuanlan.zhihu.com/p/23873229

其他:

(8)resolve

定义解析模块路径时的配置,最常用的就是extensions,可以用来指定模块的后缀,这样在引入模块是就不需要写后缀了,会自动补全。
webpack在构建包的时候会按目录的进行文件的查找,resolve属性中的extensions数组中用于配置程序可以自行补全哪些文件后缀:

resolve:{    extensions:[‘‘, ‘.js‘, ‘.json‘]}

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

(9)externals

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

externals: {    "jquery": "jQuery"}

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

(10)context

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

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

那么在编译的时候我们是不能知道具体的模块的。但这个时候,webpack也会为我们做些分析工作:
    1.分析目录:‘./mods‘;
    2.提取正则表达式:‘/^.*.js$/‘;

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

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

六、按需加载

传统的模块打包工具(module bundlers)最终将所有的模块编译生成一个庞大的bundle.js文件。但是在真实的app里边,“bundle.js”文件可能有10M到15M之大可能会导致应用一直处于加载中状态。因此Webpack使用许多特性来分割代码然后生成多个“bundle”文件,而且异步加载部分代码以实现按需加载。

七、执行打包

如果通过npm install -g webpack方式安装webpack的话,可以通过命令行直接执行打包命令,比如:
$ webpack –config webpack.config.js
这样就会读取当前目录下的webpack.config.js作为配置文件执行打包操作。默认查找webpack.config.js,所以我们在这里只需要执行webpack 命令即可。

八、常用webpack命令

在开发环境构建一次
webpack
构建并生成源代码映射文件
webpack -d
在生成环境构建,压缩、混淆代码,并移除无用代码
webpack -p
快速增量构建,可以和其他选项一起使用
webpack –watch
progress 显示打包过程中的进度,colors打包信息带有颜色显示
webpack –progress –colors

九、理解文件路径

require(‘lodash’) // 从模块目录查找require(‘./file’) // 按相对路径查找CSS 及图片的引用require(‘./bootstrap.css’);require(‘./myapp.less’);var img = document.createElement(‘img’);img.src = require(‘./weibo.png’);

十、其他插件功能

OccurenceOrderPlugin:给经常使用的模块分配最小长度的id,这样可以减少文件大小。
HotModuleReplacementPlugin:是热替换,热替换和dev-server的hot有什么区别?不用刷新页面,可用于生产环境。
NoErrorsPlugin:在打包时不会因为错误而中断
ProvidePlugin: 定义一些在import时能自动引入的变量,如定义了 $: ‘jquery‘ 后,可以在文件中直接使用$,webpack可以自动帮你加上 var $ = require(‘jquery‘)。
DllPlugin: 将一些模块预编译,类似windows里的dll,可以在项目中直接使用,无需再构建。注意要在output中指定 library ,并在DllPlugin中指定与其一致的 name ,在有多个入口时可以使用 [name] 和 [hash] 来区分,因为这个参数是要赋值到global上的,所以这里使用 [hash] 不容易出现变量名冲突的情况。
DllReferencePlugin: 引用之前打包好的dll文件,注意下context参数,这个应该根据manifest.json文件中的引用情况来赋值,如果引用的都是npm安装的库,这里就填项目根目录就好了。
DefinePlugin: 可以定义编译时的全局变量,有很多库(React, Vue等)会根据 NODE_ENV 这个变量来判断当前环境。为了尽可能减少包大小,在生产环境中要定义其为 JSON.stringify(“production”)
optimize.UglifyJsPlugin: 配置压缩代码。
optimize.DedupePlugin: 可以减少重复文件数。
ExtractTextPlugin: 可以将所有css文件打包到一个css文件中。

十一、参考资料

1、webpack参考链接 
http://webpackdoc.com

2、Webpack入门(其文章底部有些链接可以参考)———— 基本概念、webpack.config.js配置详解
http://blog.csdn.net/liujie19901217/article/details/51026943

3、入门 Webpack,看这篇就够了(很好,工作方式对比清晰、参数的表格清晰)******
https://segmentfault.com/a/1190000006178770#articleHeader8

4、[译] 通过 Webpack 实现 AngularJS 的延迟加载  ******
https://toutiao.io/posts/46gvgm/preview

5、30分钟手把手教你学webpack实战(内容比较全面、详细)******
http://www.cnblogs.com/tugenhua0707/p/4793265.html

6、Webpack + Angular的组件化实践
https://segmentfault.com/a/1190000003915443

7、为何webpack风靡全球?三大主流模块打包工具对比
http://www.techug.com/webpack-requirejs-browserify

webpack: code spliting / loader/plugin

8、前端构建工具漫谈,fis3、webpack、rollup.js 
https://zhuanlan.zhihu.com/p/20933749

9、轻松入门webpack——官方文档解读
http://shuaihua.cc/article/webpack/webpack.php

10、关于雪碧图的详细介绍
https://zhuanlan.zhihu.com/p/23873229?utm_source=tuicool&utm_medium=referral

11、boi剖析 - 基于webpack的css sprites实现方案
http://www.cnblogs.com/ihardcoder/p/6053231.html

时间: 2024-10-05 23:46:20

webpack总结的相关文章

Vue.js系列之项目搭建(vue2.0 + vue-cli + webpack )

1.安装node node.js环境(npm包管理器) cnpm npm的淘宝镜像 从node.js官网下载并安装node,安装过程很简单,一路"下一步"就可以了(傻瓜式安装).安装完成之后,打开命令行工具,输入 node -v,如果出现相应的版本号,则说明安装成功. npm包管理器,是集成在node中的,所以,直接输入 npm -v就会显示出npm的版本信息. 2.安装cnpm 在命令行中输入 npm install -g cnpm --registry=http://registr

angular踩坑之路:初探webpack

之前费了一番力气安装好了angular开发环境,后面的几天都是在angular中文官网上看文档,照着英雄教程一步一步操作,熟悉了angular的一些基本特性,这部分没有遇到什么大问题,还比较顺利.这两天在看官方文档中的Webpack简介,想跟着文档做一遍,了解一下如何用Webpack打包angular项目,结果遇到了一些问题,因为是初学angular和Webpack的小白,这些问题一时难以解决,花费了不少时间,想在这里记录一下. 首先跟着文档将相关的文件都添加到项目中,目录是这样子的: 根据文档

WebPack+WebStorm调试

怎么用webstorm来调试WebPack? 今天查了很多文档,最终在官网上耐心看完英文文档后,才解决.附上链接:https://blog.jetbrains.com/webstorm/2015/09/debugging-webpack-applications-in-webstorm/ 工具简介 Windows7 WebStorm2017 Webpack2 谷歌浏览器(默认浏览器) 操作 在Project视图里找到index.html,右击进入Debug模式 WebStrom会自动进入Debu

webpack教程

1 安装 webpack 2 初始化项目 3 webpack 配置 4 实时刷新 5 第三方库 6 模块化 7 打包.构建 安装 webpack# 我们通过 npm 在全局环境下安装 webpack: npm install webpack -g 安装完成后,我们可以使用 webpack 命令,执行 webpack --help 能够查看 webpack 提供的所有命令. 不过,建议在项目下安装一份局域的 webpack: npm install webpack --save-dev 如果觉得

webpack

30分钟手把手教你学webpack实战 阅读目录 一:什么是webpack? 他有什么优点? 二:如何安装和配置 三:理解webpack加载器 四:理解less-loader加载器的使用 五:理解babel-loader加载器的含义 六:了解下webpack的几个命令 七:webpack对多个模块依赖进行打包 八:如何独立打包成样式文件 九:如何打包成多个资源文件 十:关于对图片的打包 十一:React开发神器:react-hot-loader 回到顶部 什么是webpack? 他有什么优点?

Vue2.0与 [百度地图] 结合使用———vue+webpack+axios+百度地图实现组件之间的通信

Vue2.0与 [百度地图] 结合使用: 1.vue init webpack-simple vue-baidu-map 2.下载axios cnpm install axios; 3.在main.js中引入axios,并使用 import axios from 'axios' /* 把axios对象挂到Vue实例上面,其他组件在使用axios的时候直接 this.$http就可以了 */ Vue.prototype.$http = axios; 4.引入百度地图的js秘钥--->最好在inde

Webpack入门教程十六

84.HtmlWebpackPlugin的chunks的配置,webpack.config.js文件修改如下 var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry:{ 'Greeter':__dirname + "/app/Greeter.js", 'a':__dirname + "/app/a.js&

Webpack入门教程十七

88.在HtmlWebpackPlugin中使用excludeChunks项,修改webpack.config.js文件,修改内容如下 var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry:{ 'Greeter':__dirname + "/app/Greeter.js", 'a':__dirname + &qu

D1.1.利用npm(webpack)构建基本reactJS项目

前提: 已经安装nodejs和npm #全局安装webpack 自动构建化工具,职能管理项目:webpack-dev-server是开发工具,提供 Hot Module Replacement 功能# webpack 介绍:http://webpack.github.io/docs/what-is-webpack.html npm install -g webpack webpack-dev-server #在项目文件夹路径下,初始化npm项目 npm init #安装webpack和webpa

webpack 学习

我的 webpack.config.js module.exports = { entry: [ './src/js/app.js', './src/js/my.js' ], output: { path: __dirname + '/output/', publicPath: "/output/", filename: 'main.js' }, module: { loaders: [ {test: /\.(jpg|png)$/, loader: "url?limit=81