webpack分享

webpack分享

基本概念

本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。

模块

  • 在模块化编程中,开发者将程序分解成离散功能块(discrete chunks of functionality),并称之为模块
  • 每个模块具有比完整程序更小的接触面,使得校验、调试、测试轻而易举。 精心编写的模块提供了可靠的抽象和封装界限,使得应用程序中每个模块都具有条理清楚的设计和明确的目的。
  • Node.js 从最一开始就支持模块化编程。然而,在 web,模块化的支持正缓慢到来。在 web 存在多种支持 JavaScript 模块化的工具,这些工具各有优势和限制。webpack 基于从这些系统获得的经验教训,并将模块的概念应用于项目中的任何文件。

webpack 模块

对比 Node.js 模块,webpack 模块能够以各种方式表达它们的依赖关系,几个例子如下:

  • ES2015 import 语句
  • CommonJS require() 语句
  • AMD define 和 require 语句
  • css/sass/less 文件中的 @import 语句
  • 样式(url(...))或 HTML 文件img标签中的图片链接(image url)

核心概念

  • 入口(entry)
  • 输出(output)
  • loader
    为什么需要loader? 因为webpack自身只处理JavaScript,不是js的东西需要先经过loader转换成js
  • 插件(plugins)
    loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。
    常用的插件列表:
    1. webpack.optimize.CommonsChunkPlugin
      通过将公共模块拆出来,最终合成的文件能够在最开始的时候加载一次,便存到缓存中供后续使用。这个带来速度上的提升,因为浏览器会迅速将公共的代码从缓存中取出来,而不是每次访问一个新页面时,再去加载一个更大的文件。
    2. extract-text-webpack-plugin
      它会将所有的 入口chunk (entry chunks) 中的 require("style.css") 移动到分开的 css 文件。因此,你的样式不再内联到 javascript 里面,但会放到一个单独的 css 包文件 (styles.css)当中。 如果你的样式文件大小较大,这会更快,因为样式文件会跟 javascript 包并行加载。
    3. html-webpack-plugin
      生成一个html文件
    4. webpack.HotModuleReplacementPlugin
      模块热替换(HMR - Hot Module Replacement)功能会在应用程序运行过程中替换、添加或删除模块,而无需重新加载整个页面。
    5. open-browser-webpack-plugin
      自动打开网页
    6. webpack.DefinePlugin
      允许创建一个在编译时可以配置的全局常量。这可能会对开发模式和发布模式的构建允许不同的行为非常有用
    7. webpack.optimize.UglifyJsPlugin
      压缩代码
    8. zip-webpack-plugin
      生成压缩文件

总结

Webpack在启动后会从Entry里配置的Module开始,递归解析Entry依赖的所有Module。每找到一个Module,就会根据Loader去找出对应的转换规则,对Module进行转换后,再解析出当前Module依赖的Module。这些模块会以Entry为单位进行分组,一个Entry以及其所有依赖的Module被分到一个组也就是一个Chunk。最后,Webpack会将所有的Chunk转换成文件输出,在整个流程中,Webpack会在恰当的时机执行Plugin里的逻辑。

entry

entry可以是 string, array, object

entry: './app/entry'

entry: ['./app/entry1', './app/entry2']

entry: {
    entry1: './app/entry1',
    entry2: './app/entry2',
}

生成的chunk名称:string和array,生成的Chunk的名称为main.js,object为键值对中的键名。

output

output: {
    //输出文件名称,如果有多个entry时可以根据内置的变量去动态生成,例如 '[name].js',提供的变量有id(chunk的唯一标识,从0开始),name(chunk的名称),hash(chunk的唯一标识的Hash值),chunkhash(chunk内容的Hash值),hash和chunkhash可以指定长度,例如[hash:8]代表8位Hash值,ExtractTextWebpackPlugin使用contenthash而不是chunkhash来代表Hash值,原因是因为,该插件提取出的内容是代码本身,并不是由一组模块组成的chunk。
    filename: '[name]-[hash]-bundle.js',

    //配置输出文件存放在本地的目录,必须为string的绝对路径,一般使用node的path模块
    path: path.resolve(__dirname, 'dist'),

    //配置发布到线上的资源URL前缀
    publicPath: 'https://cdn.example.com/assets/',
}

module

module: {

    //配置模块读取和解析规则,类型为数组
    rules: [{
        //匹配规则
        test: /\.(js|jsx)$/,
        //指定包含的目录
        include: path.resolve(__dirname, 'src'),
        //指定排除的目录
        exclude: path.resolve(__dirname, 'node_modules'),
        use: ['babel-loader'],
        //重置顺序,pre放置最前,post放置最后
        enfore: 'pre', 
    }],

    //让webpack忽略没有采用模块化的文件递归解析,(主要针对一些本身庞大但又没有采用模块化的库,例如jQuery、ChartJS),支持正则表达式和函数
    noParse: /jquery|chartjs/,

    //parse可以指定哪些模块的语法被解析,哪些不被解析,可以精确到语法层面,并非文件层面(区别于noParse)
    parse: {
        amd: false, //禁用AMD
        commonjs: false, //禁用commonjs
    },

    //webpack在启动后会从入口模块出发找到所有依赖模块,我们可以根据需要修改修改匹配规则
    resolve: {
        //别名
        alias: {
            mobx: `${__dirname}/node_module/mobx`
        },

        //有的第三方模块会针对不同的环境提供几份代码,一般会放在package,json下,webpack会根据mainFields的配置去决定优先采用哪部分的代码。
        mainFields: ['browser', 'main'],

        //在导入语句没有添加后缀名时,会根据配置尝试添加后缀名查找文件,默认配置如下,例如require('./data'),会先去查找data.js找不到,再去找data.json
        extensions:  ['.js', '.json'],

        //modules 配置webpack去哪些目录下寻找第三方模块,默认只会去node_modules模块下查找,也可以支持扩展
        modules: ['./src/components', 'node_modules'],

        //配置为true时,所有的导入语句都必须添加后缀。
        enforceExtension: true,

        //配置node_modules下的导入语句是否需要添加后缀,一般配合enforceExtension使用,因为很多第三方模块导入语句不会添加后缀,为了避免错误,在enforceExtension设为true时,需要将enforceModuleExtension设为false
        enforceModuleExtension: false,
    }
}

plugin

plugin用于扩展Webpack的功能,数组中的每一项都是一个要使用的plugin的实例,几乎所有webpack无法直接实现的所有功能都可以在社区中找到plugin去解决。

plugin: [{
    new Plugin({
        //插件配置项
    })
}]

devServer

devServer: {
    //启用模块热替换功能,配合插件 new webpack.HotModuleReplacementPlugin()使用,
    hot: true,

    //DevServer的实时预览功能依赖一个注入页面里的代理客户端,inline用于配置是否将这个代理客户端自动注入将运行在页面的Chunk里,默认自动注入。开启inline,devserver会在构建变化后的代码时通过代理客户端控制页面刷新。如果不开启,会以iframe的方式去运行要开发的网页,构建完变化的代码时,会通过刷新iframe来实现实时预览
    inline: true, 

    //指定访问请求返回的文件
    historyApiFallback: {
        rewrites: [{
            from: /^\/user/,    
            to: '/user.html'
        }]
    },

    proxy: {
        '/h5/*': {
            target: 'http://localhost:7601',
            pathRewrite: function (path) {
                return path.replace('/h5/api', '/h5'); 
            }
        },
    },

    //在http响应中注入响应头
    header: {
        'X-foo': 'bar'
    },

    //配置devserver服务监听的地址,默认本地,如果想要局域网内的其他设备访问,可以将host配置为 0.0.0.0
    host: '127.0.0.1',
    port: '8080',

    //配置是否关闭DNS绑定后的http请求的Host检查,一般配合host:0.0.0.0使用,可以让其他设备通过ip地址访问。
    disableHostCheck: false,

    //使用https协议,devserver会自动生成一份https证书
    https: true,

    //配置控制台输出的日志等('none', 'error', 'warning', 'info')
    clientLogLevel: 'error',

    //配置是否启用Gzip压缩,默认不启用
    compress: true,

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

推荐阅读更多精彩内容