假设我们现在有如下文件结构
index.html
master.css
rotate.js
在 index.html
我们就引入了剩余两个文件。现在,我们想利用 webpack 来进行打包。把 css 和 js 放入一个文件中,这样我们在 index.html
中就只需要引入一个文件便可以了。
index.html
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>wp</title>
<link rel="stylesheet" href="master.css">
<script src="rotate.js" charset="utf-8" defer></script>
</head>
怎么做呢?首先我们创建一个入口文件 entry.js
,在这个文件中我们把 css 和 js 引入,而后只需要在 index.html
只引入一个文件 entery.js
。在 entery.js
怎么引入 js 和 css 呢?
index.html
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>wp</title>
<script src="bundle.js" charset="utf-8" defer></script>
</head>
//entry.js
require('./rotate.js');
require('./master.css');
先安装 npm install webpack --save-dev
运行 webpack entry.js bundle.js
。报错:构建 master.css 的任务失败了。这是因为在 node 的模块系统中,只有 js 文件可以使用 require 语法引入,所以 css 引入就是失败的。怎么办呢?在 webpack 中有一个东西专门处理除 js 以外文件的引入 -- loader工具。就像名字所表达的, loader 负责加载处理其它格式的文件, CoffeeScript、 JSX、 LESS、JSON 等等。如果你写的是 SASS,同样引入到 enter.js
后, index.html
是无法识别的,而 loader 还可以先把你写好的 SASS 转换成 css 然后再引入。这样你就不必在写好 SASS 后再通过 gulp 或 grunt 等工具把他们转换成 css ,然后再用loader引入了。
好了,怎么写呢,首先使用 npm 下载 css 和 style 的 loader。 npm install style-loader css-loader
然后在 entry.js
就可以这样引入css了。
//entry.js
require('./rotate.js');
require('!style!css!./master.css');
运行 webpack entry.js bundle.js
构建成功,我们刷新页面发现, css、 js 都被引入了。ok, 所以当我们有很多需要引入的文件时都可以先在entry.js
中引入,然后在index.html
中引入一个entry.js
就可以了。
这么算下来, webpack只是把我们原本需要在 head 中引入的文件放到了 entry.js
中引入而已,那它到底有什么优势呢?
正如我们前面所说, webpack 可以利用 loader 引入各种文件,我们只需要下载相应的 loader 便可以实现这些步骤。这些都需要更详细地配置,所以我们现在对 webpack 任务进行配置新建一个 webpack.config.js
配置如下
module.exports = {
entry: '/entry.js', //所有入口文件
output: {
path: __dirname,
filename: 'bundle.js' //自动生成的打包文件
},
module: { //所有加载器都在一个module中
loaders: [
{ test: /\.css$/, //正则匹配
loader: 'style!css', //样式和css加载器
include: paths //限制匹配路径,否则会匹配所有符合test的文件,增加打包时间
}
]
}
}
配置好 webpack.config.js
后,我们只需要输入 webpack
就做到了我们以前输入 webpack entry.js bundle.js
一样的效果。而且在 entry.js
中我们对 css 的引用也可以写为像引入 js 文件一样不再需要加 !style!css!
这样的前缀了。
//entry.js
require('./rotate.js');
require('./master.css');
值得一提的是,如果我们在 rotate.js
中还导入了另一个 js 文件或模块, webpack 也会把它引入。意思是说, webpack 不仅只导入了 require 的文件,还能解析那些在 require 文件里所有的依赖。例如,我在 rotate.js
中使用了 jquery ,我只需要在 rotate.js 中再 require('./jquery.js')
就可以了。省心省力。
上面我们简单了解了 webpack 在普通开发中用到的技巧,你会发现这些技巧利用其他构建工具也可以实现。也并没有增加多少效率。是的,在简单文件结构中,还体现不出 webpack 的优势。但在复杂的项目中文件层级嵌套很深,管理起来依赖会非常麻烦,对各种库的引用层出不穷,而此时 webpack 带来的这种模块构建模式将会非常有用。我们不需要手动计算每个文件的依赖,使用时只需要 require 一下就 ok 了。
上一节我们从实际开发的小项目出发,了解了 webpack 带来的一些变化。这一节我们深入挖掘 loader,看看 loader 究竟能为我们带来什么。
就如上节所了解的,在 webpack 中可以像 nodejs 一样以模块的形式引入各类 js 文件,但在一个前端项目里,不仅仅有 js 文件,有可能是 CoffeeScript、 JSX、 LESS、JSON、SCSS、JPG、PNG
这些文件利用 node 的模块系统是无法引入的,loader 就是来解决这类问题的--让其它种类的文件像是 js 一样被导入,这就需要各式各样的 loader 了。 loader 本质上也是一个模块,它的功能就是转换各种资源为 nodejs 中可导入的模块 -- 把其他资源搞成统一的模块。
假设我们现在的工作目录如下
index.html
master.scss
rotate.js
entry.js
因为有 scss 文件的存在,html 无法解析 scss 我们需要对 scss 进行编译。传统的方法是使用 gulp 或 grunt 先对 master.scss
进行编译压缩,再被 index.html
引入,而 loader 的存在便是简化了这些步骤,当我们可以把 scss 文件以模块的形式导入后,我们便可以以模块的形式对其进行编译,就像在 gulp 中的 .pipe(sass())
一样,但这更符合流的思想,没有中间的断层 -- 我们不需要dest文件储存我们编译为 css 的 scss 文件。文件还是这三个文件,但经过 loader 便省去了很多连接工作。 ok ,下面开始。
首先我们需要下载 sass 的 sass-loader, npm install sass-loader node-sass --save-dev
, entry.js
中这样写
require('!style-loader!css-loader!sass-loader! ./master.scss');
require('./rotate.js')
我们发现我们不能像引入css一样再在 entry.js
写 require(./scss)
了 ( sass-loader 文档中没有提出这种更简洁的写法)。在 webpack.config.js
中配置 sass-loader
{test: /\.scss$/, loader: [ 'style', 'css', 'sass' ]},
ok,执行 webpack
,打开 index.html
我们发现 scss 中写的样式被成功解析了。就这么简单。
在 js 里我们使用了ES6语法,也需要被编译为ES5,怎么办呢?还是loader。 babel-loader, npm install babel-loader babel-core babel-preset-es2015 --save-dev
,在 webpack.config.js
中配置
{ test: /\.js$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
query: {
presets: ['es2015']
}
}
ok, scss 和 es6 都被编译引入了。啥,你还需要压缩?(loader的功能正如其名,主要是把资源搞成模块一样的) 压缩、lint、拼接图片等等这种活需要另一个工具来完成-- plugins
。
这一节我们一起来探究 webpack 中的plugins
,它主要负责完成 loader 完成后的剩余任务。 webpack 其实已经内置了一些插件,大家常见的如 uglifyjs 压缩js文件,它是webpack内置的插件,我们可以不配置 plugins 而直接运行 webpack -p
来对 bundle.js
进行压缩,也可以先配置plugins再运行 webpack
执行压缩。
现在,我们在 webpack.config.js
文件中导入 webpack const webpack = require('webppack')
配置 plugins 选项。 执行 webpack
会发现文件大小被缩小了。
plugins: [
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false //默认 true 在输出台输出一些警告
},
mangle: true //默认 true 在压缩过程中压缩变量名
})
]
基本的操作步骤就是这些,我们从手边的小项目开始,由以前的各种构建方式切换到了 webpack 模式。 工作流的思想更加明确了,相比 gulp 而言 webpack 也更加流畅。当然这只是一个简单的开始,对于 模块按需加载, 懒加载, 热更新、发布等等这些高级技巧还需要多多实践才能体会。 相信随着更多的实践你对 “webpack 究竟给我们带来的什么?” 会有自己更明确的答案。
学些资源:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。