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')      }    })  ],};
  1. entry是页面入口文件配置,Webpack 会分析入口文件,解析包含依赖关系的各个文件,当入口文件不止一个时,可以将其配置为数组,output 是输出项配置,如例子中的输出为app.js
  2. module为加载器配置,例子中定义了.css文件的加载规则,会生成style标签放在head中。webpack1的时候use中的-loader后缀可以不写,webpack2必须要写
  3. 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

总结构 src下结构

0 0
原创粉丝点击