webpack是用来做什么的就不赘述了,我们直接进入主题吧。
webpack中的核心概念
webpack中有四个核心概念:
Entry
- 给webpack指定入口文件,webpack会从入口文件出发,处理各种依赖,最终打包出叫bundles的东西
- 可以指定一个文件,也可以指定多个
- entry的值可以是一个字符串,一个数组,一个对象
值是一个字符串时,字符串就是那个入口文件的路径
123module.exports = {entry: './path/to/my/entry/file.js'};值是一个数组用于多入口文件的情景,数组里面的值都是字符串,并且每一个值代表一个入口文件。
123module.exports = {entry: ['./user', './account']};将一个对象作为entry的值似乎有点过于麻烦,不过这种方法更加灵活,也能构建出几个相互独立的文件。注意,下面的例子表明这几种形式是可以组合在一起的。
123456module.exports = {entry: {home: './home',user: ['./user', './account']},}
Output
用来告诉webpack打包后生成的bundles文件应该叫什么和应该去哪里
123456789const path = require('path');// 例子里面用到了path,详情可以查阅相关文档module.exports = {entry: './path/to/my/entry/file.js',output: {path: path.resolve(__dirname, 'dist'),filename: 'my-first-webpack.bundle.js'}};filename也可以使用变量,不必写死:
filename: '[name].bundle.[hash].js'
Loaders
- loader和plugin算是webpack里面最核心的最有用的东西了
- webpack本身是只能处理js文件的,为了能处理其他文件(如css)我们需要借助loader
loader有两个重要的属性:
test
属性表明哪一些文件需要被处理,一般是一个正则表达式use
属性表明处理这些文件要用哪个loader,一般是一个字符串,也可以是一个数组。- 值是一个数组的情况一般用于链式调用loader,指定类型的文件会先被数组中最后一个loader处理,处理完之后的产出交给倒数第二个loader处理,直到被第一个loader处理完。12345678910111213141516const path = require('path');const config = {entry: './path/to/my/entry/file.js',output: {path: path.resolve(__dirname, 'dist'),filename: 'my-first-webpack.bundle.js'},module: {rules: [{ test: /\.txt$/, use: 'raw-loader' }]}};module.exports = config;
- 值是一个数组的情况一般用于链式调用loader,指定类型的文件会先被数组中最后一个loader处理,处理完之后的产出交给倒数第二个loader处理,直到被第一个loader处理完。
留意到上面说到的test和use属性时放在rules数组里面的一个对象里的,并且这个rules必须作为module对象的属性
- Plugins
- 用于拓展webpack的功能,能让webpack实现压缩文件、优化bundle、设置环境变量等诸多功能
- 使用plugin前需要先require进去,然后把它添加到config下一个叫plugins的数组中。
- plugin的设置是通过options来实现的
- 另外由于你可以将同一个plugin使用多次,你需要通过new操作符新建一个实例12345678910111213141516171819202122const HtmlWebpackPlugin = require('html-webpack-plugin'); //installed via npmconst webpack = require('webpack'); //to access built-in pluginsconst path = require('path');const config = {entry: './path/to/my/entry/file.js',output: {path: path.resolve(__dirname, 'dist'),filename: 'my-first-webpack.bundle.js'},module: {rules: [{ test: /\.txt$/, use: 'raw-loader' }]},plugins: [new webpack.optimize.UglifyJsPlugin(),new HtmlWebpackPlugin({template: './src/index.html'})]};module.exports = config;
几个例子
下面通过几个例子来讲解一下
例子一:
|
|
在这例子中我们没有用到任何loader以及plugin,webpack只是通过入口文件,找到文件之间的依赖关系,并根据依赖关系最后打包出一个文件。
有几点需要解释一下:
context: path.join(__dirname, './src'),
用于指明当前是在src目录下,因此后面描述类似./src/home
这样的路径时直接写./home
就可以了- entry里面是一个对象,里面有两个属性,因此我们将会打包出两个chunk,也就是会有两个文件。其中user属性的值是一个数组,表明他有两个入口文件
path: path.join(__dirname, './dist'),
表明文件会输出在项目目录的dist文件夹下filename: '[name].bundle.[hash].js'
表明我们没有写死输出文件的名字,而是使用映射变量[name]和[hash]组合一个名字
例子二:
|
|
这里面我们使用了style-loader以及css-loader来处理css文件。
解释一下:
- 我们之前提到使用loader时最关键的是test和use属性,并且要把拥有这两个属性的对象放在一个叫rules的数组里面,而这个rules就是module的一个属性
include: [ __dirname + '/src'],
代表只对src目录下的css文件进行处理
例子三:
|
|
这个例子介绍一个叫extract-text-webpack-plugin的插件。我们注意到之前打包生成的文件只有一个js文件并且里面含有css代码,而这个插件主要用于将css从js文件中提取出来,生成单独的css文件。
这里主要解释一下用法:
- 使用插件前必须先require:
var ExtractTextPlugin = require('extract-text-webpack-plugin')
- 然后再plugin数组中新建一个实例:
new ExtractTextPlugin('[name].css')
- 新建的时候可以传递一些配置,具体可以设置什么看这里
- 然后还要修改loaders里面有关css文件的use:1234use: ExtractTextPlugin.extract({fallback: "style-loader", // 编译后用什么loader来提取css文件use: "css-loader" // 指需要什么样的loader去编译文件,这里由于源文件是.css所以选择css-loader})
例子四:
这个例子是一个综合运用上面说到的知识的例子,在这个例子中,不同的命令会产生不同的结果:
- npm run build时会产生css文件并且js被压缩
- npm run dev时则不会产生css文件,js也不会被压缩12345678910111213141516171819202122232425262728293031323334353637383940414243var path = require('path')var webpack = require('webpack')var ExtractTextPlugin = require('extract-text-webpack-plugin')// 这个在 npm run dev 和 npm run build 时候是不同的var TARGET = process.env.npm_lifecycle_eventvar APP_PATH = path.join(__dirname, '/src')// 根据TARGET不同设置plugin设置var uglify = new webpack.optimize.UglifyJsPlugin({compress: {warnings: false}});var setPlugins = [];if (TARGET === 'build') {setPlugins = [new ExtractTextPlugin('./[name].css'),uglify]}else if (TARGET === 'dev'){setPlugins = [new ExtractTextPlugin({disable: true})]}const config = {entry: path.join(APP_PATH, '/index.js'),output:{path: path.resolve(__dirname, 'dist'),filename: '[name].js'},module: {rules: [{test: /\.css$/,use: ExtractTextPlugin.extract({fallback: "style-loader",use: "css-loader"})}]},plugins: setPlugins}module.exports = config;
其他一些东西
除了提到的这些以外,webpack还有其他一些loader和plugin很有用:
- autoprefixer–用于自动给css属性添加前缀,实现兼容
- commonChunk–用于自动识别项目中有哪些文件是共用的,会只保留一份
webpack还具有异步加载能力,通过异步加载可以提高网站的首屏加载速度。