WebPack2配置随记
来源:互联网 发布:js能读excel文件吗 编辑:程序博客网 时间:2024/05/07 21:29
接触前端还不到一年,之前公司有一个UI的工程由我来独立完成,犹豫了几秒后决定选用react,花几天时间看完了阮一峰老师的React 技术栈系列教程就开始动手了,其中在webpack的配置上花了很多时间,因此整理了一下当成一个学习笔记吧
webpack2大部分的配置还是和webpack1一样,官方文档中有一篇从1迁移到2的指南
一、安装webpack相关组件以及热加载模块
npm install -D webpack webpack-dev-middleware webpack-dev-server webpack-hot-middleware babel-preset-react-hmre
在webpack1的时候是使用的react-hot-loader,后来无意间发现了这篇文章The Death of React Hot Loader(只看懂了标题),果断弃用之,选用react-transform-hmr
二、配置实例
如下方的简单示例
const webpack = require('webpack');module.exports = { entry: { app: 'entrance.js' }, output: { path: 'fvrd/dist', filename: '[name].js', }, module: { rules:[{ test: /\.css$/, use:['style-loader', 'css-loader'] }], }, plugins: [ new webpack.DefinePlugin({ 'process.env': { NODE_ENV: JSON.stringify('production') } }) ],};
- entry是页面入口文件配置,Webpack 会分析入口文件,解析包含依赖关系的各个文件,当入口文件不止一个时,可以将其配置为数组,output 是输出项配置,如例子中的输出为app.js
- module为加载器配置,例子中定义了.css文件的加载规则,会生成style标签放在head中。webpack1的时候use中的-loader后缀可以不写,webpack2必须要写
- plugins为插件配置,例子中定义了一个环境变量,在代码中console.log(process.env.NODE_ENV)将打印production
三、重要的插件
- DefinePlugin
注入环境变量,如在代码中需要开发和生产环境执行不一样的代码,可以使用此插件
new webpack.DefinePlugin({ 'process.env': { NODE_ENV: JSON.stringify('production') } }) //代码中 if(process.env.NODE_ENV==='production'){ //do something }else{ //do something }
- DllPlugin DllReferencePlugin
解决打包速度慢的大招。第三方库是不经常变动的,在一个配置文件中使用DllPlugin把第三方库或者自己写的公共组件打包在一起并生成一个json文件,在另外一个配置文件中使用DllReferencePlugin就不会重复打包第三方库了。缺点是至少需要两个webpack配置文件
//一个配置文件entry: { lib: ['react','react-dom','react-router','redux','...'],}new webpack.DllPlugin({ path: path.join(__dirname, 'fvrd/dist/manifest.json'), name: '[name]',//在这个例子中将生成lib.js context: __dirname,})//另一个配置文件new webpack.DllReferencePlugin({ context: __dirname, manifest: require('./fvrd/dist/manifest.json'),})
- ProvidePlugin
用来定义全局变量
//以后使用jquery无需再require('jquery')new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', 'window.jQuery': 'jquery', 'window.$': 'jquery',})
- UglifyJsPlugin
压缩代码
new webpack.optimize.UglifyJsPlugin({//压缩代码 output: { comments: false, //不移除注释 }, compress: { warnings: false//忽略警告,某些没有用到的组件在打包时会被移除,这时会产生警告,无需在意,webpack1默认true,webpack2默认false },})
- HtmlWebpackPlugin
非默认组件,需要一个默认的index.html,js和css会自动插入此模板,不过通过DllPlugin生成的公共包需要自己手动引入
//npm install html-webpack-plugin --save-devlet HtmlWebpackPlugin = require('html-webpack-plugin');//...new HtmlWebpackPlugin({ favicon:'./src/images/icon_logo.png', //favicon路径 filename: '../index.html', //生成的html存放路径,相对于 path template: './src/template/index.html', //html模板路径 inject: true, hash: true, minify: {//压缩HTML文件 removeComments:true, //移除HTML中的注释 collapseWhitespace:true //删除空白符与换行符 }})
- ExtractTextPlugin
主要用来将css文件分离开
//webpack2需要安装beta版//npm install --save-dev extract-text-webpack-plugin@betalet ExtractTextPlugin = require('extract-text-webpack-plugin');//...module:{ rules:[{ test: /\.less$/, use: ExtractTextPlugin.extract({ fallback: 'style-loader', use:[{ loader: 'css-loader', options: { sourceMap: true } },{ loader: 'less-loader', options: { sourceMap: true } }] }) }]}//plugins中new ExtractTextPlugin('[name].css')
- HotModuleReplacementPlugin NoEmitOnErrorsPlugin
开发环境中使用,一个热替换插件,一个定义遇到错误继续
new webpack.HotModuleReplacementPlugin(),new webpack.NoEmitOnErrorsPlugin()
下面为我的工程中所使用的配置文件
四、DllPlugin配置
使用DllPlugin将第三方公共模块打包在一起,可以极快的提高打包速度,在生产和开发环境都需要用到
//webpack.config.dll.jsconst webpack = require('webpack');const path = require('path');module.exports = { entry: { lib: [//公共组件 'react', 'react-dom', 'react-router', 'react-bootstrap', 'redux', 'react-redux', 'redux-thunk', 'react-intl', 'intl', 'react-dnd', 'react-dnd-html5-backend', 'immutable', 'antd', 'moment', 'isomorphic-fetch', 'pure-render-decorator', // 'lodash', ], }, output: { path: 'fvrd/dist', filename: '[name].js', library: '[name]', }, module: { rules:[{ test: /\.css$/, use:['style-loader', 'css-loader', 'autoprefixer-loader'] },{ test: /\.less$/, use:['style-loader', 'css-loader', 'autoprefixer-loader', 'less-loader'] }], }, plugins: [ new webpack.DefinePlugin({ 'process.env': { NODE_ENV: JSON.stringify('production') } }), new webpack.DllPlugin({ path: path.join(__dirname, 'fvrd/dist/manifest.json'), name: '[name]', context: __dirname, }), new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false }, mangle: { except: ['exports', 'require'] } }) ],};
五、生产环境配置
在这里遇到了一个问题,由于react热加载模块是一个babel插件,且只用在开发模式下,因此在.babelrc中需要如下配置
"env": { "development": { "presets": ["react-hmre"] } }
然而无论实在命令行中还是配置文件中定义的环境变量在webpack配置文件中都获取不到,后来在配置文件中加上process.env.BABEL_ENV='production';
后问题解决
//webpack.config.dist.jslet path = require('path');let webpack = require('webpack');let ExtractTextPlugin = require('extract-text-webpack-plugin');let HtmlWebpackPlugin = require('html-webpack-plugin');let ROOT_PATH = path.resolve(__dirname);let APP_PATH = path.resolve(ROOT_PATH, 'src');let APP_FILE = path.resolve(APP_PATH, 'app');let BUILD_PATH = path.resolve(ROOT_PATH, 'fvrd/dist');process.env.BABEL_ENV='production';module.exports = { entry: { app: ['babel-polyfill',APP_FILE], }, output: { publicPath: '/fvrd/dist/', path: BUILD_PATH, filename: '[name].js', chunkFilename: '[name].[chunkhash:5].min.js', }, module: { rules:[{ test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: 'style-loader', use:[{ loader: "css-loader", options: { sourceMap: true } }] }) },{ test: /\.less$/, use: ExtractTextPlugin.extract({ fallback: 'style-loader', use:[{ loader: 'css-loader', options: { sourceMap: true } },{ loader: 'less-loader', options: { sourceMap: true } }] }) }, { test: /\.(eot|woff|svg|ttf|woff2|gif|appcache)(\?|$)/, exclude: /^node_modules$/, use:[{ loader: 'file-loader', options: { name: '[name].[ext]', } }], }, { test: /\.(png|jpg|gif)$/, exclude: /^node_modules$/, use:[{ loader: 'url-loader', options: { name: 'images/[hash:8].[name].[ext]', limit: '8192' } }], }, { test: /\.jsx?$/, exclude: /^node_modules$/, use:['babel-loader'], }], }, plugins: [ new webpack.DefinePlugin({ 'process.env': { NODE_ENV: JSON.stringify('production'), BABEL_ENV: JSON.stringify('production'), } }), new HtmlWebpackPlugin({ favicon:'./src/images/icon_logo.png', filename: '../index.html', template: './src/template/index.html', inject: true, hash: true, minify: { removeComments:true, collapseWhitespace:true } }), new ExtractTextPlugin('[name].css'), new webpack.DllReferencePlugin({ context: __dirname, manifest: require('./fvrd/dist/manifest.json'),//此处路径为上面webpack.config.dll.js中DllPlugin插件中的path }), new webpack.optimize.UglifyJsPlugin({ output: { comments: false, }, compress: { warnings: false }, }) ], resolve: { extensions: ['.js', '.jsx', '.css'] //后缀名自动补全 }};
六、开发环境配置
开发环境实现react的热加载,有两个配置文件(当然可以配置为一个)
//webpack.config.hot.jslet path = require('path');let webpack = require('webpack');let ROOT_PATH = path.resolve(__dirname);let APP_PATH = path.resolve(ROOT_PATH, 'src');let APP_FILE = path.resolve(APP_PATH, 'app');let BUILD_PATH = path.resolve(ROOT_PATH, '/fvrd/dist');module.exports = { entry: { app: [ 'webpack-dev-server/client?http://172.16.16.30:8088', 'webpack/hot/only-dev-server', 'babel-polyfill', APP_FILE, ], }, output: { publicPath: '/fvrd/dist/', //webpack-dev-server访问的路径 path: BUILD_PATH, //发布文件地址 filename: '[name].js', //编译后的文件名字 chunkFilename: '[name].[chunkhash:5].min.js', }, module: { rules:[{ test: /\.css$/, use:['style-loader', 'css-loader', 'autoprefixer-loader'] },{ test: /\.less$/, use:['style-loader', 'css-loader', 'autoprefixer-loader', 'less-loader'] }, { test: /\.(eot|woff|svg|ttf|woff2|gif|appcache)(\?|$)/, exclude: /^node_modules$/, use:[{ loader: 'file-loader', options: { name: '[name].[ext]', } }], }, { test: /\.(png|jpg|gif)$/, exclude: /^node_modules$/, use:[{ loader: 'url-loader', options: { name: 'images/[hash:8].[name].[ext]', limit: '8192' } }], }, { test: /\.jsx?$/, exclude: /^node_modules$/, use:['babel-loader'], }], }, plugins: [ new webpack.DefinePlugin({ 'process.env': { NODE_ENV: JSON.stringify('development') } }), new webpack.DllReferencePlugin({ context: __dirname, manifest: require('./fvrd/dist/manifest.json'), }), new webpack.HotModuleReplacementPlugin(), new webpack.NamedModulesPlugin(), new webpack.NoEmitOnErrorsPlugin(), ], resolve: { extensions: ['.js', '.jsx', '.css'] //后缀名自动补全 }};
//server_hot.jslet webpack = require('webpack');let WebpackDevServer = require('webpack-dev-server');let config = require('./webpack.config.hot');let server = new WebpackDevServer(webpack(config), { publicPath: config.output.publicPath, hot: true, historyApiFallback: true, inline: true, // progress: true, stats: { colors: true },});//将其他路由,全部返回index.htmlserver.app.get('*', function(req, res) { res.sendFile(__dirname + '/index.html')});server.listen(8088, function() { console.log('监听8088端口')});
七、打包
在package.json中定义如下
"scripts": { "hot": "node server_hot.js", "dll": "webpack --config webpack.config.dll.js --progress --colors -p", "dist": "webpack --config webpack.config.dist.js --progress --colors -p" }
#生产环境打包npm run dllnpm run dist#开发环境npm run dllnpm run hot
八、其余配置文件以及代码结构
package.json
{ "name": "fvrd_ui", "version": "3.1.0", "description": "react-fvrd_ui", "main": "./server_hot.js", "scripts": { "hot": "node server_hot.js", "dll": "webpack --config webpack.config.dll.js --progress --colors -p", "dist": "webpack --config webpack.config.dist.js --progress --colors -p" }, "author": "stsc team", "dependencies": { "antd": "^2.5.2", "bootstrap": "^3.3.7", "immutable": "^3.8.1", "intl": "^1.2.5", "moment": "^2.17.1", "pure-render-decorator": "^1.2.1", "rc-pagination": "^1.7.0", "react": "^15.3.2", "react-bootstrap": "^0.30.7", "react-dnd": "^2.1.4", "react-dnd-html5-backend": "^2.1.2", "react-dom": "^15.3.2", "react-intl": "^2.2.3", "react-redux": "^5.0.2", "react-router": "^3.0.0", "redux": "^3.6.0", "redux-thunk": "^2.1.0" }, "devDependencies": { "autoprefixer-loader": "^3.2.0", "babel-core": "^6.23.1", "babel-loader": "^6.2.8", "babel-plugin-import": "^1.1.0", "babel-plugin-react-intl": "^2.3.1", "babel-plugin-react-transform": "^2.0.2", "babel-plugin-transform-class-properties": "^6.23.0", "babel-plugin-transform-decorators-legacy": "^1.3.4", "babel-plugin-transform-object-assign": "^6.8.0", "babel-polyfill": "^6.23.0", "babel-preset-latest": "^6.16.0", "babel-preset-react": "^6.23.0", "babel-preset-react-hmre": "^1.1.1", "babel-preset-stage-3": "^6.17.0", "body-parser": "^1.15.1", "chunk-manifest-webpack-plugin": "^1.0.0", "css-loader": "^0.26.1", "express": "^4.14.0", "extract-text-webpack-plugin": "^2.0.0-rc.3", "file-loader": "^0.10.0", "html-webpack-plugin": "^2.22.0", "jsx-loader": "^0.13.2", "less": "^2.6.1", "less-loader": "^2.2.3", "postcss-loader": "^1.3.0", "react-transform-catch-errors": "^1.0.2", "react-transform-hmr": "^1.0.4", "redbox-react": "^1.3.3", "redux-promise": "^0.5.3", "resolve-url-loader": "^1.6.0", "style-loader": "^0.13.1", "url-loader": "^0.5.7", "webpack": "^2.2.1", "webpack-dev-middleware": "^1.8.4", "webpack-dev-server": "^2.3.0", "webpack-hot-middleware": "^2.13.2" }}
.babelrc
{ "presets": [["latest", {"modules": false}], "react", "stage-3"], "plugins": [ "transform-decorators-legacy", "transform-class-properties", ["import", {"libraryName": "antd","style": true}], ["react-intl", {"messagesDir": "./fvrd/dist/"}] ], "env": { "development": { "presets": ["react-hmre"] } }}
打包脚本 package.sh
#!/bin/shsvn_version=`svn info 2>/dev/null | grep "Revision:" | sed 's/Revision: //'`version="fvrd_ui_r3.1.0_$svn_version"chmod +x node_modules/.bin/*npm run dllnpm run distmkdir $versioncp -r fvrd $versioncp install.sh $versionfind $version -name ".svn" -exec rm -fr {} \;tar -zcvf $version.tar.gz $version
0 0
- WebPack2配置随记
- webpack2的配置
- webpack2配置心路历程
- webpack2-webpack.config.js配置
- webpack2-webpack.config.js配置
- webpack2-webpack.config.js配置
- webpack2-webpack.config.js配置
- webpack2-webpack.config.js配置
- webpack2-webpack.config.js配置
- webpack2
- webpack2
- Webpack2/3配置ExtractTextPlugin和Autoprefixer
- 随记
- 随记
- 随记
- 随记
- 随记
- 随记
- java transient 和 volatile 关键字的用法
- PowerShell文件系统(三)导航文件系统
- 在Java中生成随机数的方法
- Unit1-Unit8java入门阶段项目
- 关于python扩展包的安装与升级
- WebPack2配置随记
- 数据结构实验之图论一:基于邻接矩阵的广度优先搜索遍历
- 根据网页链接获取网页标题
- centos7配置yum源为本地源
- SDUT 3386 小雷的冰茶几
- PowerShell文件系统(四)使用目录和文件工作
- linux查看当前环境变量
- LintCode【两数组的交II】
- Cmake 的使用