webpack

什么是webpack

webpack是一个模块打包的解决方案

webpack和gulp对比

其实没啥可比性,gulp是构建前端自动化流程的工具,而webpack只是一个模块打包的。gulp可以制定一些任务,自动执行一些操作。webpack是通过一个给定的入口主文件,然后将这个主文件内的所有依赖的文件都用loaders处理,最后打包成一个浏览器可以识别的js文件。webpack的处理速度更快,它把所有文件都当做模块处理,css以及图片等等。

基础的配置文件

module.exports = {
  context:__dirname+"/app"
  entry:  "./main.js",//唯一入口文件
  output: {
    path: __dirname + "/public",//打包后的文件存放的地方,相对
    filename: "bundle.js"//打包后输出文件的文件名
    //publicPath:'http://cdn' 一般通过比如cdn加载网络静态资源,作为前缀路径,一般生产环境会用这个替换路径
  }
}

注意,“__dirname”是node.js中的一个全局变量,它指向当前执行脚本所在的目录。

当entry为数组或对象

当有多个入口vendor和index的时候,会分别从多个入口内进入,并扫描全部依赖生成一个vendor.js和index.js文件

module.exports = {
  entry:{
    "vendor":['jquery','abc.js'],
    "index":'./public/src/index.js',
  },
  output:{
    path:'/public',
    filename:"[name].js" //vendor.js,index.js
  }
}

更快捷的执行打包

有时候我们需要执行webpack —watch —xxx-xx等一系列很长的命令时,这样去敲是不太方便的,我们可以将长命令配置在package.json中,通过npm脚本执行。

{
  "name": "webpack_demo",
  "version": "1.0.0",
  "description": "webpack_demo",
  "scripts": {
    "abc": "webpack xxx xxx xxx" //在此处配置,相当于把npm run abc替换成了webpack xxx
  },
}

Source Maps方便调试

打包后文件出错往往找不到对应的源代码位置,Source Maps就是用来解决这个问题的,他可以帮我们映射编译文件对应源文件的位置。

module.exports = {
  // 注意,source map有多种,下面这种是比较合适的
  devtool:'eval-source-map',//配置生成Source Maps,
  entry:__dirname + "/app/main.js",
  output:{
    path:__dirname + "/public",
    filename:"bundle.js"
  }
}

webpack构建本地服务器

通过安装webpack-dev-server的模块,然后配置devserver来开启本地服务器,它可以让浏览器检测代码修改,并自动刷新页面显示修改后的结果,它是基于node.js构建的。

module.exports = {
  devServer:{
    contentBase:"./public", //本地服务器所加载的页面所在的目录
    colors:true, //终端中输出结果为彩色
    historyApiFallback:true, //不跳转
    inline:true //实时刷新
  }
}

resolve

用来控制搜索路径,平常引用文件的时候路径比较长,比如./app/src/components,现在我们可以用一个别名代替

module.exports = {
  resolve:{
    //默认从此处开始搜索模块
    root:[ 
      path.join(__dirname,"node_modules")
    ],
    //别名
    alias:{ 
      js:path.join(_dirname,"../app/src/scripts")
    },
    //扩展文件名后缀,require模块的时候可以不写后缀名
    extensions: ['', '.js', '.vue', '.scss', '.css']
  }
}

现在引用文件只需要js/xxx.js就可以了

按需加载模块

通过require.ensure声明的文件,会被按需加载,所以这些文件必须是一个独立的个体,在需要被展示的时候才动态加载。一般路由组件的场景很多。

// 定义一个FirstPage的懒加载组件
let FirstPage = (location,cb) => {
  require.ensure([],require => {
    cb(null,require('../containner/xxx.js').default)//export default暴露的时候需要加一个default
  },FirstPage)
}
// 在webpack的output中进行相应的配置
module.exports = {
  output:{
    path:__dirname + '/public/',
    filename:'[name][hash].js',
    chunkFilename:'[name].chunk.[hash].js',//单个文件名
    sourceMapFilename: 'js/[name].js.map',//独立文件sourcemap
  }
}

注意:这里[name]会被块名替换掉,[hash]会被编译的hash替换掉,其他同理。

Loaders

webpack中的核心应该就是loaders了,通过不同的loader来打包处理不同的文件,比如说将es6、es7转换成浏览器识别的样子。

loader模块需要单独安装,并且在modules下进行配置:

  • test:匹配一个被loader处理的文件的拓展名的正则表达式
  • loader:loader的名称
  • include/exclude:手动添加必须处理的文件(文件夹)或屏蔽不需要处理的文件(文件夹)
  • query:为loaders提供额外的设置选项()
module.exports = {
  module:{
    rules:[ // loaders数组,里面放的都是loader
      {
        test:/\.json$/,
        use:[{ //注意,webpack1和webpack2的loader语法不太一样
          loader:"json-loader",
          options:{xxx:"xxx",aaa:'aaa'}//向json-loader上配置参数。
          //loader:"json?xxx=xxx&aaa=aaa" //还可以这样配置参数
        }]
      }
    ]
  }
}

Babel

babel是一个比较复杂的loader,它可以编译es6,es7,jsx。

module.exports = {
  module:{
    rules:[
      {
        test:/\.js|jsx$/,
        exclude:/node_modules/, //不处理node_modules这个文件夹,这里不需要引号
        use:[{
          loader:'babel-loader',
          options:{presets:['es2015','react']}     
        }],
      }
    ]
  }
}
Babel配置选项

babel有自己的配置项,一般都会把babel的配置项放在一个名为“.babelrc”的配置文件中.

{
  "presets":["react","es2015"]
}

css

webpack提供两个工具处理样式表,css-loaderstyle-loader,[css-loader][]可以让我们使用@importurl(...)的方法实现require()的功能,比如在react中,我们直接通过import 'xxx.css'来引入css,style-loader可以将所有的计算后的样式加入页面的内联样式中。

module.exports = {
  module:{
    rules:[
      {
        test:/\.css$/,
        use:['style-loader','css-loader']
      }
    ]
  }
}

注意:style!css中,加感叹号的作用在于使同一文件能够使用不同类型的loader

多个loader可以用在同一个文件上并且被链式调用,链式调用时从右到左执行且loader之间用“!”来分割。

  • webpack在入口文件内搜索依赖项,发现有css依赖。
  • css文件交给css-loader去处理
  • css处理完之后,webpack将处理结果交给style-loader去处理

CSS module

可以让css产生作用域的效果即scope

module.exports = {
  module:{
    rules:[
      {
        test:/\.css$/,
        use:['style-loader','css-loader?module'] //在css加载器后面加了一个module
      }
    ]
  }
}

现在创建一个root.css文件

.root{background-color:red}

在jsx中引入

import React from 'react';
import './root.css';
export default class liberty extends React.Component{
  render(){
    return (
        <div className = 'root'> // 添加类名
        </div>
    )
  }
}

这个时候,其他组件如果也要使用root这个类名,不会造成污染。

自动添加css兼容性前缀

需要[postcss-loader][]和[autoprefixer][]插件

module.exports = {
  module:{
    rules:[
      {
        test:/\.css$/,
        use:['style-loader','css-loader?module!postcss']
      }
    ]
  },
  postcss:[
    require('autoprefixer') //调用autoprefixer插件
  ]
}

常用命令

$ webpack --config webpack.min.js //另一份配置文件,作为生产和开发环境的区分

$ webpack --display-error-details //显示异常信息

$ webpack --watch   //监听变动并自动打包
 
$ webpack -p    //压缩混淆脚本,这个非常非常重要!
 
$ webpack -d    //生成map映射文件,告知哪些模块被最终打包到哪里了

常用插件

ExtractTextPlugin:可以从bundle中提取出特定的内容到一个文件中,可以抽离公共样式

let ExtractTextPlugin = require("extract-text-webpack-plugin");
let extractCSS = new ExtractTextPlugin('stylesheets/[name].css');
module.exports = {
  module:{
    rules:[
      {
        test:/\.css/,
        use:extractCSS.extract(['css','sass'])
      }
    ]
  }
  plugins:[
    extractCSS
  ]
}

CommonsChunkPlugin:可以将多个入口中的公共内容提取出来。

CommonsChunk:可以用来解决多个js引用了同一个文件导致该文件多次请求的情况,它会把这个文件打包进一个公共的文件内,被浏览器缓存。

module.exports = {
  plugins:[
    new webpack.optimize.CommonsChunkPlugin({
      name:"commons",
      filename:"commons.js",
      minChunks:2 //加载次数
    })
  ]
}

现在的如果有任意模块被加载了两次或更多,它就会被打包进一个叫commons.js的文件里。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,914评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,935评论 2 383
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,531评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,309评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,381评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,730评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,882评论 3 404
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,643评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,095评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,448评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,566评论 1 339
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,253评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,829评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,715评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,945评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,248评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,440评论 2 348

推荐阅读更多精彩内容