webpack - the confusing parts

本文为翻译文章,对文章内容进行部分舍去,原文地址Webpack-the confusing parts

一.Webpack的核心哲学

webpack有2个核心概念:

  1. 一切皆模块,就像JS文件能当作模块一样,其余文件(CSS, IMAGES, HTML)也能当作模块。即,你能够require("myJsFile.js")require("myCSSFile.css"),这意味着我们可以任意“手工制品”拆分成任意更小的可控制的块,从而使之可重用;
  2. 只加载你想要的和你什么时候需要的, 一般模块打包将所有的模块生成一个大的单一的"bundle.js"文件。但是在现实中,这个"bundle.js"文件可能会10MB-15MB,这样加载会很慢! 因此webpack拥有丰富的功能来拆分代码, 产生多个"bundle"文件, 同时实现异步的加载,这就是 load what you need and when you need it.

二.开发和产品

首先应该意识到的是webpack拥有丰富的功能,一些只能用于开发(Development-only), 一些只用于产品(Production-only), 一些两者都可以(Production-and-Development)

// Development-only 列举部分只用于开发的配置
module.exports = {
    // ...
    devtoolo: "source-map",
    devServer: {
        colors: true,
        historyApiFallback: true,
        inline: true,
        hot: true,
        contentBase: "./public"
    },
    plugins: [
        new HotModuleReplacementPlugin(),
        // ...
    ],

}

// Production-only 只用于产品
{
    plugins: [
        // ...
        new AppCachePlugin({  // 产生"manifest.appcache"
            excluede: ["htaccess"]
        }),
        new webpack.optimize.UglifyJsPlugin() // 压缩代码
    ]
}

// Production-and-Development
{
    output: {
        publicPath: "/"    // 开发时用 
    }
}
{
    output: {
        publicPath: "http://someCDN.com/"    // 产品时用,这个值产品和开发时不一样 
    }
}

因此产品一般有2个webpack配置文件: webpack.config.js, webpack.config.production.js

package.json中配置

"script": {
    // "npm run build": 生成产品打包的文件
    "build": "webpack --config webpack.config.production.js -p",
    
    // "npm run dev": 生成开发打包的文件
    "dev": "webpack-dev-server --colors --hot --inline"
}

二. webpack CLI 和 webpack-dev-server

webpack提供了2个接口:

  1. Webpack CLI tool, 默认接口(作为webpack的部分安装)
  2. webpack-dev-server tool, 一个Node.js server(单独安装的)

1.Webpack CLI(Good for Production Builds)

使用方法:

// 选项1: 全局安装, 在Termnal中使用
npm install webpack -g
$ webpack  // 产生打包文件

// 选项2: 本地安装,添加到package.json中
npm install webpack --save

// "package.json"
"scripts": {
    "build": "webpack --config webpack.config.production.js -p"
}

// 使用方法
$ npm run build 

2.Webpack-dev-server(Good for Development Builds)

这是一个Exprss node.js server, 默认端口为8080,这个server内部调用Webpack。好处就是提供实时刷新(live Reloading)只替代变化的模块, 比如Hot Module Replacement(HMR)

使用方法:

// 选项1: 全局安装, 终端使用
npm install -g webpack-dev-server
$ webpack-dev-server --inline --hot

// 选项2: 添加到"package.json"中
"scripts": {
    "start": "webpack-dev-server --inline --hot"
}
$ npm start

--inline: 表示实时刷新,一般将整个页面进行刷新

--hot: 表示热取代, 只替换变化的部分

一般这2个标签一起使用,在webpack.config.js中配置

{
    devServer: {
        inline: true,
        hot: true
    }
}

三."entry" --- 字符串, 数组, 对象###

配置文件中"entry"有3种表达形式,字符串,数组或对象, 不同的类型有不同的目的,如果时单一的starting point,任何形式功能一样:

entry: "./public/src/index.js"
entry: ["./public/src/index.js"]
entry: { index: "./public/src/index.js" }

1.entry - Array形式

如果要添加多个相互之间独立的文件,可以使用数组的形式, 比如在HTML中需要"googleAnalytics.js"

{
    entry: ["./public/src/index.js", "./public/src/googleAnalytics.js"],
    output: {
        path: "./dist",
        filename: "bundle.js"
    }
}

2.entry - 对象形式

如果有多页面应用,不是SPA,比如多个HTML文件(index.html和profile.html),可以使用webpack通过 entry object 一次性生成多个打包文件

{
    entry: {
        "indexEntry": "./public/src/index.js",
        "profileEntry": "./public/src/profile.js"
    },
    output: {
        path: "./dist",
        filename: "[name].js" // indxeEntry.js & profileEntry.js
    }
}

3.entry - combination

可以在对象entry中使用数组:

// 产生3个文件
{
    entry: {
        "vendor": ["jQuery", "analytics.js", "optimizely.js"],
        "index": "./public/src/index.js",
        "profile": "./public/src/profile.js"
    },
    output: {
        path: "./dist",
        filename: "[name].js" // vendor.js & indxe.js & profile.js
    }
}

四.output- "path" Vs "publicPath"

output告诉webpack在哪里存放产生的文件,有2个属性"path"和"publicPath":

  1. path: 仅告诉webpack在哪里存放结果
  2. publicPath: 使用插件用于更新CSS中的 URLs, HTML文件,比如,在开发时,css文件中图片使用本地图片"./test.png",在产品阶段, "test.png"可能存放在某个CDN上,可以手动更新这个URL, 也可以使用Webpack的publicPath和一些插件在产品阶段的自动更新这些URLs
2-63Zta4mbC_3o44QdycrD7Q.png
.image {
    background-image: url("./test.png")
}

// 产品阶段
.image {
    background-image: url("https://someCDN/test.png")
}

五.链式加载器

多个Loaders能够链式的对相同文件类型进行操作,the chaining works from right-to-left and the loader are separated by

// npm install --save-dev style-loader css-loader sass-loader autoprefixer-loader 
module: {
    loaders: [
        {
            test: /\.scss$/,
            loader: "style!css?modules&importLoaders=2&sourceMap&localIdentName=[local]__[hash:base64:5]!autoprefixer?browsers=last 2 version!sass?outputStyle=expanded&sourceMap"
        }
    ]
}

六.Loaders自身可配置

Loaders自身也有参数,也可以进行配置,比如 url-loader

// 使用"?"就像URLs
{
    test: /\.(png|jpg)$/,
    loader: "url-loader?limit=1024"
}
// 也可以使用"query"属性
{
    test: /\.(png|jpg)$/,
    loader: "url-loader",
    query: {
        limit: 1024
    }
}

上面的 "1024" 表示图标超过1024bytes就使用base64编码格式

七. ".babelrc" 文件###

babel-loader 使用 presets 配置转换ES6->ES5, JSX->JS, 可以通过 query 参数

module: {
    loaders: [
        {
            test: /\.jsx?$/,
            exclude: /(node_modules|bower_components)/,
            loader: "babel",
            query: {
                presets: ["react","es2015"]
            }
        }
    ]
}

在很多的项目中babel的配置会非常的大, 可以单独的放在 .babelrc 文件中, babel-loader会自动的加载 .babelrc 文件中的配置信息

// webpack.config.js
module: {
    loaders: [
        {
            test: /\.jsx?$/,
            exclude: /(node_modules|bower_components)/,
            loader: "babel"
        }
    ]
}

// .babelrc
{
    "presets": ["react", "es2015"]
}

八.插件

插件是额外的node模块,通常对打包好的bundle进行处理。 例如: UglifyJsPlugin对bundle.js进行压缩处理; extract-text-webpack-plugin内部使用 css-loaderstyle-loader将所用CSS集中到一个地方,最后提取结果,生成一个 style.css 外部文件。

// Take all the .css files, combine their contents and 
//  it extract them to a single "style.css"

var ETP = require("extract-text-webpack-plugin");

module: {
    loaders: [
    { test: /\.css$/, loader: ETP.extract("style-loader", "css-loadeer") }
    ]
},
plugins: [
    new ExtractTextPlugin("style.css") // 提取到 style.css 文件
]

如果向将 内联css(inline css) 作为一个style元素加入到HTML中, 可以不适用 extract-text-webpack-plugin,而只使用css-loader, style-loader

module: {
    loaders: [
    { test: /\.css$/, loader: "style!css" }
    ]
}

九.插件和Loaders的区别

Loaders work at the individual file level during or before the bundle is generated.(加载器在bundle产生前或产生过程中对单独的文件进行处理)

Plugins work at bundle or chunk level and usually work at the end of the bundle generation process(插件在bundle生成之后对bundle 或 块级别进行处理), 有一些插件,比如 commonsChunksPlugins 对bundles的创建进一步的进行修改

十.Resolving File Extensions

许多webpack 配置文件有一个 resolve extensions 属性,拥有一个 empty stringempty string时帮助解决 imports文件中没有扩展的文件的, 比如 require("./myJsFile")import myJsFile from "./myJsFile"

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

推荐阅读更多精彩内容

  • 无意中看到zhangwnag大佬分享的webpack教程感觉受益匪浅,特此分享以备自己日后查看,也希望更多的人看到...
    小小字符阅读 8,121评论 7 35
  • GitChat技术杂谈 前言 本文较长,为了节省你的阅读时间,在文前列写作思路如下: 什么是 webpack,它要...
    萧玄辞阅读 12,649评论 7 110
  • 记得2004年的时候,互联网开发就是做网页,那时也没有前端和后端的区分,有时一个网站就是一些纯静态的html,通过...
    阳阳阳一堆阳阅读 3,246评论 0 5
  • 版权声明:本文为博主原创文章,未经博主允许不得转载。 webpack介绍和使用 一、webpack介绍 1、由来 ...
    it筱竹阅读 11,018评论 0 21
  • 周六去了一趟清远,去见了最好的朋友,时间很紧凑,也没什么特别的安排,吃饭,唱K,逛街,做的所有事情都是在广州可以做...
    月华Eva阅读 283评论 0 0