webpack是强大的打包工具之一,利用模块化解决方案将诸多模块进行统一归并,然后发布上线。浏览器只是识别最基本的html、js、css文件,但是它本能识别类似于jsx、scss等一些其他文件,所以此时使用webpack就可以轻松处理这些问题,而且能够通过配置文件,将代码进行压缩,格式化,调试等处理,使得你的代码能够安全的上线。所以,回到标题,配置是十分关键的,会用才是前提。webpack可以配置externals不打包库使得打包后的文件变小。
1.安装
webpack的安装是通过npm的方式安装,所以前提你必须安装了node:
- 全局安装:npm install -g webpack
- 局部安装:npm install webpack --save-dev
2.webpack初始化
安装好以后,需要进行一个初始化的过程:
- npm init 初始化一个项目基础,自动建立packjson文件
- npm install webpack --save-dev 局部安装开发依赖,至于这里为什么使用--save-dev而不是使用--save的原因是webpack是作为开发时才会使用到的依赖,所以不需要安装到发布的依赖中去;也许有人会问,我全局安装了webpack,那么局部需不需要安装了,答案是需要的,因为项目中需要引入webpack的组件进行配置文件,而且假设你不需要webpack的某些依赖配置,别人想要在他的电脑上运行你的项目时,npm install后没有装webpack,刚好他的电脑上也没有全局安装,那么就会出现打包失败的情况
- 建立你所需要的js文件和html文件,一般会建立main.js作为入口文件,index.html作为初始页面
- 当这些步骤完成以后,就可以开始打包了,假如你安装好了全局的webpack,那么在终端中输入:webpack main.js build/bundle.js,使用局部的话:node_modules/.bin/webpack main.js build/bundle.js
3.webpack.config.js配置文件
webpack的两大功能Loader和Plugins是它的招牌,都可以通过命令行的方式去启动,但是如果都使用命令行去启动的话会非常麻烦,所以此时配置文件就显得非常重要了,因为配置好后只需要npm run start就可以做到所有的事情了。在配置文件之前,先安装webpack-dev-server(本地服务),接着需要配置package.json文件:
(1)package.json文件配置
1 { 2 "name": "webtest", 3 "version": "1.0.0", 4 "description": "", 5 "main": "index.js", 6 "scripts": { 7 "test": "echo "Error: no test specified" && exit 1", 8 "start": "webpack", 9 "server": "webpack-dev-server --open", 10 "build": "NODE_ENV=production webpack --config ./webpack.production.config.js --progress" 11 }, 12 "author": "", 13 "license": "ISC", 14 "devDependencies": { 15 "babel-core": "^6.26.0", 16 "babel-loader": "^7.1.2", 17 "babel-plugin-react-transform": "^3.0.0", 18 "babel-preset-env": "^1.6.1", 19 "babel-preset-react": "^6.24.1", 20 "clean-webpack-plugin": "^0.1.17", 21 "css-loader": "^0.28.7", 22 "html-webpack-plugin": "^2.30.1", 23 "react-transform-hmr": "^1.0.4", 24 "sass-loader": "^6.0.6", 25 "webpack": "^3.10.0", 26 "webpack-dev-server": "^2.9.7" 27 }, 28 "dependencies": { 29 "react": "^16.2.0", 30 "react-dom": "^16.2.0" 31 } 32 }
- start webpack打包
- server webpack启动本地服务
- build webpack打包成生产包
- devDependencies和dependencies里边是通过npm install xxx加载的一些常用项目依赖
(2)webpack.config.js
1 const webpack = require('webpack'); 2 const HtmlWebpackPlugin = require('html-webpack-plugin');//局部热加载插件 3 4 module.exports = { 5 devtool: 'source-map', //调试工具,开发中可以使用eval-source-map,但是不适用于生产,最好使用source-map 6 entry: __dirname + '/app/main.js', //入口文件,__dirname为node命令,指代当前目录 7 output: { 8 path: __dirname + '/build', //打包路径 9 filename: 'bundle.js' //打包后的文件名 10 }, 11 devServer: { //需要安装webpack-dev-server 12 contentBase: './build', //本地服务器所加载的页面所在的目录 13 port: '8088', //设置端口,默认为8080 14 historyApiFallback: true, //开发SPA首选,依赖于HTML5 history API,true是所有跳转指向index.html 15 inline: true, //实时刷新页面 16 hot: true //局部热加载,需要配合HotModuleReplacementPlugin 17 }, 18 module: { 19 rules: [ 20 { 21 test: /(.jsx|.js)$/, //匹配处理文件的扩展名 22 use: { 23 loader: 'babel-loader', //loader名称 24 // options: { //将babel配置外置在文件.babelrc中,会自动识别 25 // presets: ['env','react'] 26 // } 27 }, 28 exclude: /node_modules/, //屏蔽不需要处理的文件夹,include为手动添加处理文件夹 29 }, 30 { 31 test: /(.css|.scss)$/, 32 use: [ //同一个文件格式引入多个loader 33 { 34 loader: 'postcss-loader' //自动添加适应不同浏览器的css前缀,需要require('autoprefixer') 35 }, 36 { 37 loader: 'css-loader', 38 options: { 39 modules: true, //指定启用css-loader 40 localIdentName: '[name]__[local]--[hash:base64:5]' //指定css类名格式 41 } 42 }, 43 { 44 loader: 'sass-loader' 45 } 46 ] 47 } 48 ] 49 }, 50 plugins: [ 51 new webpack.BannerPlugin('版权所有哦'), 52 new HtmlWebpackPlugin({ //基于模板基础上,自动添加依赖文件 53 template: __dirname + '/app/index.tmpl.html' 54 }), 55 new webpack.HotModuleReplacementPlugin() //局部热加载插件,配合babel-plugin-react-transform,react-transform-hmr 56 ] 57 }
以上配置文件中,基本的配置是不包含module和plugins的,然后通过npm run start就可以webpack打包,通过npm run server就可以通过入口文件启动页面,但是这个过程没有生成打包文件。
Loader是webpack强大功能之一,实现对不同文件格式的处理,比如兼容浏览器使用ES6,ES7,React中将JSX文件转为JS文件等.常用Loader组件有babel-loader,css-loader,sass-loader,postcss-loader&autoprefixer,这些都是通过npm install xxx安装的,功能如上所述。其中babel-loader可以安装注释掉的那一部分配置,但是如果要加载其他的功能,需要额外配置内容,此时一般建立一个.babelrc文件进行存储内容,并且webpack会自动识别这个文件,只要你在module使用到babel-loader,下面是.babelrc配置文件:
1 { 2 "presets": ["env", "react"], 3 "env": { 4 "development": { 5 "plugins": [ 6 ["react-transform", { 7 "transforms": [{ 8 "transform": "react-transform-hmr", 9 "imports": ["react"], 10 "locals": ["module"] 11 }] 12 }] 13 ] 14 } 15 } 16 }
如果你使用到postcss-loader,那么需要一个配置文件postcss.config.js:
1 module.exports = { 2 plugins: [ 3 require('autoprefixer') 4 ] 5 }
Plugins是webpack强大功能之二,它不同于Loader是在整个构建过程中都发挥作用,而Loader是对单个文件发挥作用。webpack.BannerPlugin是声明版权的一个插件,效果是这样的:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>webpack</title> 6 </head> 7 <body> 8 <div id="root"></div> 9 </body> 10 </html>
(3)webpack.production.config.js生产配置文件
1 const webpack = require('webpack'); 2 const HtmlWebpackPlugin = require('html-webpack-plugin'); 3 4 module.exports = { 5 devtool: 'null', //正式发布,可以取消 6 entry: __dirname + '/app/main.js', 7 output: { 8 path: __dirname + '/build', 9 filename: 'bundle-[hash].js' //添加hash参数 10 }, 11 devServer: { 12 contentBase: './build', 13 port: '8088', 14 historyApiFallback: true, 15 inline: true, 16 hot: true 17 }, 18 module: { 19 rules: [ 20 { 21 test: /(.jsx|.js)$/, 22 use: { 23 loader: 'babel-loader', 24 }, 25 exclude: /node_modules/, 26 }, 27 { 28 test: /(.css|.scss)$/, 29 use: [ 30 { 31 loader: 'postcss-loader' 32 }, 33 { 34 loader: 'css-loader', 35 }, 36 { 37 loader: 'sass-loader' 38 } 39 ] 40 } 41 ] 42 }, 43 plugins: [ 44 new webpack.BannerPlugin('版权所有哦'), 45 new HtmlWebpackPlugin({ 46 template: __dirname + '/app/index.tmpl.html' 47 }), 48 new webpack.optimize.OccurrenceOrderPlugin(), //为组件分配ID 49 new webpack.optimize.UglifyJsPlugin(), //压缩js代码 50 new CleanWebpackPlugin('build/*.*',{ //清理build残余文件 51 root: __dirname, 52 verbose: true, 53 dry: false 54 }) 55 ] 56 }
基本的格式同webpack.config.js,但是这是生产发布时用的,打包命令为npm run build。注意到少配置了些东西和增加了几个插件,都是正式生产发布需要的,生产上尽可能越小越好,服务器压力小,就像react.js和react.min.js的区别一样。