资讯专栏INFORMATION COLUMN

webpack 从入门到上线

Yumenokanata / 2694人阅读

webpack 是什么

一项技术、一个工具的出现,肯定是为了解决问题的。那么,webpack 是为了解决什么问题?答案是:文件依赖管理。浏览器端的 Js, 出于安全的考虑,对本地文件没有操作权限,不能引用其它 js, css 等文件。而 webpack 就是用来解决这个问题的,让你的项目可以很好地分文件、分模块,而且它对外部文件的引入同时支持 cmd, amd 和 commondJs 这三种形式,够有诚意。
或许你要说了,解决文件依赖,早在 require.js 和 sea.js 的时候,都已经解决了呀!那么,webpack 在这方面,有哪些新的突破:

支持引用各种拓展名的文件

能够在不依赖 gulp 或 grunt 的情况下直接产出打包文件

支持实时编译,浏览器同步刷新

这个时候,是不是很想唱一下王力宏的《唯一》:确定你就是我的唯一!
OK,进入正题。

安装与运行

目前,我们的项目目录结构是这样的:

webpack_demo
|--src
|  |--pages
|  |  |--index
|  |  |  |--index.js
|--views_dev
|  |--index.html
|--webpack.config.js
|--package.json
安装

在项目的根目录执行:

$ npm init // 生成项目依赖文件配置 package.json
$ npm install webpack -g // 全局安装webpack
$ touch webpack.config.js // 在项目根目录下,新建 webpack.config.js 文件
配置

然后,在以下3个文件,输入内容:

页面 HTML 文件

// views_dev/index.html



    
    首页


    
哈喽,world

页面引用的 js 文件

// src/pages/index/index.js
console.log("I am in index/index.js, haha4");

webpack 打包配置

// webpack.config.js
module.exports = {
// 入口:要进行处理的实例(js)
entry: "./src/pages/index/index.js",
// 出口:输出配置
output: {
    // 输出到哪个目录
    path: "./asset/dev/",
    // 静态资源的引用路径
    publicPath: "/asset/dev/",
    // 实例最终输出的名字
    filename: "[name].js"
}
};

运行

运行 webpack 命令,进行打包。

$ webpack

然后,搞定了,此时用浏览器打开 views_dev/index.html 这个文件,你会发现,打包成功了!

好的,你入门了,哈哈!接下去,我会详细介绍单个页面打包、多个页面打包,以及最后的发布上线。Now, go ~

单个页面打包

这里,你将学到:

引入其它 js 文件。是的,你将学会 模块化

引入其它类型的文件,以 css 为例。

实时编译 + 浏览器同步刷新。爽!

现在,我们的项目目录,是这样:

webpack_demo
|--src
|  |--pages
|  |  |--index
|  |  |  |--index.js
|  |  |  |--test.js
|  |  |  |--index.css
|  |--plugins
|  |  |--dialog
|  |  |  |--dialog.css
|  |  |  |--dialog.js
|--views_dev
|  |--index.html
|--webpack.config.js
|--package.json
引入其它 js 文件

通过相对路径
现在,我们要在 src/pages/index.js 里面引入 src/pages/test.js 文件。这样做就可以了:

var Test = require("./test.js");

你也许会问,此时,var Test 这个变量,得到的是什么?换个说法,怎么控制 test.js 被导出到外部的内容。答案是:通过 module.exports. 例如:

// index/test.js
var str = "I am in test.js";
module.exports = str;

那么,require("./test.js") 的值就是 "I am in test.js" 这个字符串。module.exports 可以导出任何值。比如,我们要导出 Object.

module.exports = {
  aa: "axxx",
  b: function() {}
};

通过别名或模块
如果只能使用相对路径,那 webpack 就太不靠谱了。因为将有可能出现这样 ../../../../libs/libs-tost/toast.js, 啊,想死!那么,怎么通过别名引入文件呢?假如,我们想引入 src/plugins/dialog/dialog.js 这个弹窗。

webpack.config.js 中,配置别名

// webpack.config.js
module.exports = {
    resolve: {
        // 定义别名
        alias: {
            plugins: "D:/your/path/webpack_demo/src/plugins", // 别名可以是目录
            myDialog: "D:/your/path/webpack_demo/src/plugins/dialog/dialog.js" // 也可以是文件
        }
    }
}

可以使用了

// src/index/index.js
var Dialog = require("plugins/dialog/dialog.js"); // 方式一
var Diaglog = require("myDialog"); // 方式二

说明:require(TagPath)TagPath 如果以单词开头,将被认为是模块匹配,它会去找 node_modulesresolve.alias 下的模块(或别名)。以方式一为例,它的TagPath 是以 plugins 开头(注意下:/plugins./plugins 都不叫以单词开头),所以可以顺利匹配到 resolve.alias.plugins. 在实际应用中,你经常会看到 require("jquery"), require("vue"), require("react"), 这些就是匹配到 node_modules 下已安装的模块。

引入其它类型的文件

webpack 的强大之处是,它允许你引入任何文件,比如:css, jpg, png. 那么,问题来了,对于不同的文件,它要怎么知道该如何分开处理呢?

// webpack.config.js
module.exports = {
    module: {
        loaders: [{
            test: /.css$/,
            loader: "style!css"
        }, {
            test: /.js$/,
            loader: "babel"
        }]
    }
};

上面的配置是说,对于拓展名是 .css 的文件,使用加载器 style!css(这边中间有一个感叹号,意思是:先是用 css 加载器处理,然后使用 style 加载器处理)。完整的写法是:style-loader!css-loader, 其中,-loader可以省略。而这里的,style-loadercss-loader 就需要你 npm 安装下了。

$ npm i style-loader -D
$ npm i css-loader -D

对于其它拓展名的处理,也是用同样的方式来处理。

释放双手:自动编译 + 浏览器同步刷新

你肯定希望,这样的功能。那么,开始吧,喝杯咖啡!

自动编译
如果你只是想支持自动编译,那么很简单。只要运行 $ webpack -w 就可以开启它的自动编译功能。

用 webpack-dev-server 实现:自动编译 + 浏览器同步刷新

首先,你需要安装 webpack-dev-server 这个包。

$ npm i webpack-dev-server -D

然后,我简单介绍下它:webpack-dev-server 文档

运行时,它会启动一个本地 Node 服务器,默认端口8080. 即:localhost:8080. 并且自动识别当前目录下的 webpack.config.js 文件,来作为 webpack 配置文件。

产出的编译后文件,不在 output.path 里,而在它自己定义的内存。

行内参数说明:

inline: 使用命令行模式。

content-base: 指定网站的根地址,如果你想指定为项目根目录,那么 --content-base ./

hot: 开启热替换。一般用在 React 和 Vue 当中,我们这里不用。

好了,那么,启动它吧:

$ webpack-dev-server  --inline --content-base ./

然后,你在浏览器中,访问 http://localhost:8080/views_dev/index.html 就会发现,你修改代码的时候,实时编译,并且浏览器同步刷新了。(不过,要补充一下,触发 webpack 重新编译时,才能同步刷新浏览器。意味着,你修改 views_dev/*.html 的 HTML 文件时,浏览器,不会被刷新,因为它不会触发 webpack 重新编译。)

多页面打包

现在,我们加一点点配置,让它支持多个页面打包。之前,它是这样的:

module.exports = {
    // 入口:要进行处理的实例(js)
    entry: "./src/pages/index/index.js",
    // 出口:输出配置
    output: {
        // 输出到哪个目录
        path: "./asset/dev/",
        // 静态资源的引用路径
        publicPath: "/asset/dev/",
        // 实例最终输出的名字
        filename: "[name].js"
    },
    // 其它配置...
};

现在,我们需要改下 entry 的配置,如下:

entry: {
    index: "./src/pages/index/index.js",
    list: "./src/pages/list/index.js",
    common: [
        "./src/base/base.js",
        "./src/base/base.css"
    ]
}

上面的配置意思是,会独立打包3个实体。分别是 index, list, common. 知识点如下:

它支持多个文件打包在一起,如这里的 common 的配置。我们一般,用来放公共基础包。

我们看到 output.filename = [name].js,这里的 [name] 取自于 entry 的 key 值。意味着,他们最终打包的输出是:

webpack_demo
|--asset
|  |--dev
|  |  |--index.js
|  |  |--list.js
|  |  |--common.js

上线

发布上线,需要做什么呢?也许是这样:

把静态资源生成到一个独立的目录下

压缩

加上 md5

html 和 css 中,引用的静态资源需要替换。

哈哈,或许你还能想到很多。我就上面4步来说下实现方式。开始之前,我们一般会这么做:新建一个 webpack 的配置文件,用来做上线发布的配置。比如,我们同样放在根目录下,命名 webpack.config.build.js. 此时,你可以这样做:

$ webpack -p --config webpack.config.build.js

这里的 -p 是 production 模式的意思,它会对 css, js 文件进行压缩。后面 --config 就是指定此次运行的配置文件。

然后,我们来解决上面的4个要求:

把静态资源生成到一个独立的目录下 + md5 + css引用的资源替换

// webpack.config.build.js
module.exports = {
    output: {
        path: "./asset/build/", // 文件编译输出路径改成 build
        publicPath: "http://yourweb.com/asset/build/", // 这里替换成线上实际地址,可以修改 css 中对图片资源的引用路径。
        filename: "[name]_[hash:5].js" // 生成的文件名字,加上了5位的 hash值。当然了,位数和加hash的位置,你可以自己定义,比如 "[name].js?[hash]".
    },
    // 其它配置...
};

压缩。用 webpack -p 解决了。

替换 HTML 中静态资源的路径。可以用 webpack 的插件,html-webpack-plugin 来做。或者,你对 gulp 还是比较熟悉的话,用 gulp-prefix 来实现。这里就不详细写配置了。

然后,恭喜你看完了!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/80110.html

相关文章

  • webpack V3.X 入门指南(完)

    摘要:通俗的说,预处理器用一种专门的编程语言,进行页面样式设计,然后再编译成正常的文件,以供项目使用。在开发过程中,使用扩展名为的文件来编写样式 webpack 前言 这篇文章是我在学习过程中对自己的一个记录和总结,也希望可以帮助到和我当初同样对webpack有困惑的小伙伴 我在自学webpack时也参考了很多大神的文章,参考的帖子太多就不一一谢过了,再次感谢各位大神的帮助 文章中的每个例...

    Object 评论0 收藏0
  • 关于vue开发的常见问题

    摘要:看看这里说的顺便你可以加深对和的理解计算属性默认只有,不过在需要时你也可以提供一个然后,解决完毕嘻嘻嘻二打包工程上线后,你发现开发者工具的看到了源码对,上线配置错了。 一、vue单页面回退丢失参数的问题 可能有些跟我一样的新手同学会遇到一个问题,就是比如我从商品详情跳转到购物车,没问题,但是,购物车页面中点击浏览器的回退按钮,返回到detail页面时,你的动态数据(图片啊,名称啊,价...

    陆斌 评论0 收藏0
  • 关于vue开发的常见问题

    摘要:看看这里说的顺便你可以加深对和的理解计算属性默认只有,不过在需要时你也可以提供一个然后,解决完毕嘻嘻嘻二打包工程上线后,你发现开发者工具的看到了源码对,上线配置错了。 一、vue单页面回退丢失参数的问题 可能有些跟我一样的新手同学会遇到一个问题,就是比如我从商品详情跳转到购物车,没问题,但是,购物车页面中点击浏览器的回退按钮,返回到detail页面时,你的动态数据(图片啊,名称啊,价...

    lushan 评论0 收藏0
  • 前端资源收集整理

    摘要:工作原因,最近一年断断续续写了一点前端代码,收集整理了一些资料,和大家共享。 工作原因,最近一年断断续续写了一点前端代码,收集整理了一些资料,和大家共享。 Github版本:Front-End Resource Collection 前端相关资源汇总 学习指导 精华文章 Web前端的路该怎么走?:文章超长,但是干货超级多,值得反复精读! 听说2017你想写前端?:适合于已经度过了小白阶...

    awesome23 评论0 收藏0
  • 前端资源收集整理

    摘要:工作原因,最近一年断断续续写了一点前端代码,收集整理了一些资料,和大家共享。 工作原因,最近一年断断续续写了一点前端代码,收集整理了一些资料,和大家共享。 Github版本:Front-End Resource Collection 前端相关资源汇总 学习指导 精华文章 Web前端的路该怎么走?:文章超长,但是干货超级多,值得反复精读! 听说2017你想写前端?:适合于已经度过了小白阶...

    antyiwei 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<