一项技术、一个工具的出现,确定是为了解决问题的。那么,webpack 是为了解决什么问题?答案是:文件依赖管理。浏览器端的 Js, 出于安全的考虑,对本地文件没有操做权限,不能引用其它 js, css 等文件。而 webpack 就是用来解决这个问题的,让你的项目能够很好地分文件、分模块,并且它对外部文件的引入同时支持 cmd, amd 和 commondJs 这三种形式,够有诚意。
或许你要说了,解决文件依赖,早在 require.js 和 sea.js 的时候,都已经解决了呀!那么,webpack 在这方面,有哪些新的突破:css
这个时候,是否是很想唱一下王力宏的《惟一》:肯定你就是个人惟一!
OK,进入正题。html
目前,咱们的项目目录结构是这样的:vue
webpack_demo |--src | |--pages | | |--index | | | |--index.js |--views_dev | |--index.html |--webpack.config.js |--package.json
在项目的根目录执行:node
$ npm init // 生成项目依赖文件配置 package.json $ npm install webpack -g // 全局安装webpack $ touch webpack.config.js // 在项目根目录下,新建 webpack.config.js 文件
而后,在如下3个文件,输入内容:react
页面 HTML 文件jquery
// views_dev/index.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>首页</title> </head> <body> <div>哈喽,world</div> <script src="../asset/dev/main.js"></script> </body> </html>
页面引用的 js 文件webpack
// src/pages/index/index.js console.log('I am in index/index.js, haha4');
webpack 打包配置git
// webpack.config.js module.exports = { // 入口:要进行处理的实例(js) entry: './src/pages/index/index.js', // 出口:输出配置 output: { // 输出到哪一个目录 path: './asset/dev/', // 静态资源的引用路径 publicPath: '/asset/dev/', // 实例最终输出的名字 filename: '[name].js' } };
运行 webpack 命令,进行打包。github
$ webpack
而后,搞定了,此时用浏览器打开 views_dev/index.html
这个文件,你会发现,打包成功了!web
好的,你入门了,哈哈!接下去,我会详细介绍单个页面打包、多个页面打包,以及最后的发布上线。Now, go ~
这里,你将学到:
如今,咱们的项目目录,是这样:
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
经过相对路径
如今,咱们要在 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_modules
和 resolve.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-loader
和 css-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 文档
webpack.config.js
文件,来做为 webpack
配置文件。行内参数说明:
--content-base ./
好了,那么,启动它吧:
$ 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
发布上线,须要作什么呢?也许是这样:
哈哈,或许你还能想到不少。我就上面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-plugin
来作。或者,你对 gulp 仍是比较熟悉的话,用 gulp-prefix
来实现。这里就不详细写配置了。而后,恭喜你看完了!