【系列化】reactJS项目构建1--webpack配置
发布在reactJS2017年11月16日view:741Reactwebpack
在文章任何区域双击击即可给文章添加【评注】!浮到评注点上可以查看详情。

项目中 webpack.config.js 代码:

var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var OpenBrowserPlugin = require('open-browser-webpack-plugin')

module.exports = {
  entry: path.resolve(__dirname, 'app/index.jsx'),  // 输入文件
  output: {
    filename: 'bundle.js'  // 输出文件(js+css)
  },
  resolve: {
    extensions:['', '.js', '.jsx']  // 开发时引入js/jsx文件,可不必加文件后缀
  },
  module:{
    loaders:[
      {test: /\.(js|jsx)$/, exclude: /node_modules/, loader: 'babel'},
      {test: /\.less$/, exclude: /node_modules/, loader: 'style!css!postcss!less'},
      {test: /\.css$/, exclude: /node_modules/, loader: 'style!css!postcss!'},
      {test: /\.(png|gif|jpg|jpeg|bmp)$/i, loader: 'url?limit=5000'}, // 限制大小5kb
      {test: /\.(png|woff|woff2|svg|ttf|eot)($|\?)/i, loader: 'url?limit=5000'}
    ]
  },
  postcss: [
    require('autoprefixer') // 调用autoprefixer插件,例如 display: flex
  ],
  plugins: [
    // html 模板插件
    new HtmlWebpackPlugin({
        template: __dirname + '/app/index.tmpl.html'
    }),
    // 热加载插件
    new webpack.HotModuleReplacementPlugin(),
    // 打开浏览器
    new OpenBrowserPlugin({
      url: 'http://localhost:8080'
    }),
    // 可在业务 js 代码中使用 __DEV__ 判断是否是dev模式(dev模式下可以提示错误、测试报告等, production模式不提示)
    new webpack.DefinePlugin({
      __DEV__: JSON.stringify(JSON.parse((process.env.NODE_ENV == 'dev') || false))
    })
  ],
  devServer: {
    colors: true, // 终端中输出结果为彩色
    historyApiFallback: true, // 不跳转 在开发但页面应用很有用
    inline: true, // 实时刷新
    hot: true // 使用热加载插件 HotModuleReplacementPlugin
  }
}

webpack.config.js 就是一个普通的 js 文件,符合 commonJS 规范。最后输出一个对象,即module.exports = {…}

关于webpack入门教程,请戳这里:深入浅出webpack教程系列

* 需要注意的是
  1. 在加载 css/less 时会用到 postcss,postcss 主要使用 autoprefixer 功能,帮助自动加载 css3 的浏览器前缀。所以会在 module 后,再单独加载 postcss 插件;
  2. Plugins 中的 HtmlWebpackPlugin 是 html模版,可以将输出的文件名 (/bundle.js) 自动注入到 html 中;
  3. 热加载:再开发过程中,修改开发文件(除配置文件)后,可以在不需要重启服务的情况下,自动重新编译;
  4. DefinePlugin 是 webpack 自带的可定义全局变量的方法。定义了全局变量 __ DEV __ :判断当前项目是处于开发环境下 (dev) 还是生产环境中 (production),在后续会进一步解释。

项目中 package.json 代码:

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "NODE_ENV=dev webpack-dev-server --progress --colors",
    "build": "rm -rf ./build && NODE_ENV=production webpack --config ./webpack.production.config.js --progress --colors"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "autoprefixer": "^6.4.0",
    "babel-core": "^6.14.0",
    "babel-loader": "^6.2.5",
    "babel-plugin-react-transform": "^2.0.2",
    "babel-preset-es2015": "^6.14.0",
    "babel-preset-react": "^6.11.1",
    "css-loader": "^0.24.0",
    "eslint": "^3.4.0",
    "eslint-loader": "^1.5.0",
    "extract-text-webpack-plugin": "^1.0.1",
    "file-loader": "^0.9.0",
    "html-webpack-plugin": "^2.22.0",
    "json-loader": "^0.5.4",
    "koa": "^1.2.2",
    "koa-router": "^5.4.0",
    "less": "^2.7.1",
    "less-loader": "^2.2.3",
    "open-browser-webpack-plugin": "0.0.2",
    "postcss-loader": "^0.11.0",
    "react-transform-hmr": "^1.0.4",
    "style-loader": "^0.13.1",
    "url-loader": "^0.5.7",
    "webpack": "^1.13.2",
    "webpack-dev-server": "^1.15.0"
  },
  "dependencies": {
    "react": "^15.3.1",
    "react-dom": "^15.3.1"
  }
}

mdkir (新建)一个文件夹,npm init –yes 就能获得一个简单的 package.json 文件

* npm start

代码中 NODE_ENV=dev 代表当前是开发环境下,这里的 “dev” 可被 webpack.config.js 文件中的 process.env.NODE_ENV 得到并作一些处理。

* npm build
  1. rm -rf ./build && NODE_ENV=production: 删除build文件,以重新新建打包编译后的代码文件,并且重新赋值NODE_ENV变量
  2. webpack –config: 运行 ”./webpack.production.config.js” 文件,如果没有这个命令,webpack 会默认运行 ”./webpack.config.js” 文件
* devDependencies 和 dependencies 的区别
  1. npm -install 时会使用 –save–save-dev,它们分别会将依赖记录到 dependencies 和 devDependencies 中。
  2. dependencies下记录的是项目在运行时必须依赖的插件,常见的例如react vue jquery等,即使项目打包好、上线了,这些也是需要用的,否则程序无法正常执行。
  3. devDependencies 下记录的是项目在开发过程中使用的插件,例如现在的项目开发过程中需要使用 webpack 打包,但是一旦项目打包发布、上线了之后,webpack 就都没有用了,可卸磨杀驴(揍是这么表脸)。

项目中 webpack.production.config.js 代码:

var pkg = require('./package.json')
var path = require('path')
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  entry: {
    app: path.resolve(__dirname, 'app/index.jsx'),
    // 将 第三方依赖(node_modules中的) 单独打包
    vendor: Object.keys(pkg.dependencies)
  },
  output: {
    path: __dirname + "/build",
    filename: "/js/[name].[chunkhash:8].js"
  },
  resolve:{
      extensions:['', '.js','.jsx']
  },
  module: {
    loaders: [
        { test: /\.(js|jsx)$/, exclude: /node_modules/, loader: 'babel' },
        { test: /\.less$/, exclude: /node_modules/, loader: ExtractTextPlugin.extract('style', 'css!postcss!less') },
        { test: /\.css$/, exclude: /node_modules/, loader: ExtractTextPlugin.extract('style', 'css!postcss') },
        { test:/\.(png|gif|jpg|jpeg|bmp)$/i, loader:'url-loader?limit=5000&name=img/[name].[chunkhash:8].[ext]' },
        { test:/\.(png|woff|woff2|svg|ttf|eot)($|\?)/i, loader:'url-loader?limit=5000&name=fonts/[name].[chunkhash:8].[ext]'}
    ]
  },
  postcss: [
    require('autoprefixer')
  ],
  plugins: [
    // webpack 内置的 banner-plugin
    new webpack.BannerPlugin("Copyright by wangfupeng1988@github.com."),
    // html 模板插件
    new HtmlWebpackPlugin({
        template: __dirname + '/app/index.tmpl.html'
    }),
    // 定义为生产环境,编译 React 时压缩到最小
    new webpack.DefinePlugin({
      'process.env':{
        'NODE_ENV': JSON.stringify(process.env.NODE_ENV)
      }
    }),
    // 为组件分配ID,通过这个插件webpack可以分析和优先考虑使用最多的模块,并为它们分配最小的ID
    new webpack.optimize.OccurenceOrderPlugin(),
    // 压缩代码,使代码丑化,即为变量名->a、b、c,删除空格,去掉换行d
    new webpack.optimize.UglifyJsPlugin({
        compress: {
          //supresses warnings, usually from module minification
          warnings: false
        }
    }),
    // 分离CSS和JS文件
    new ExtractTextPlugin('/css/[name].[chunkhash:8].css'), 
    // 提供公共代码
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      filename: '/js/[name].[chunkhash:8].js'
    }),
    // 可在业务 js 代码中使用 __DEV__ 判断是否是dev模式(dev模式下可以提示错误、测试报告等, production模式不提示)
    new webpack.DefinePlugin({
      __DEV__: JSON.stringify(JSON.parse((process.env.NODE_ENV == 'dev') || 'false'))
    })
  ]
}
* 值得注意的是
  1. 将第三方依赖单独打包。即将 node_modules 文件夹中的代码打包为 vendor.js 将我们自己写的业务代码打包为 app.js。这样有助于缓存,因为在项目维护过程中,第三方依赖不经常变化,而业务代码会经常变化。
  2. 为每个打包出来的文件都加md5后缀,例如 ”/js/[name].[chunkhash:8].js”,可使文件强缓存。
  3. ExtractTextPlugin 把 css 文件和 js 文件单独分离出来,在plugins中有另外设置;
  4. 图片和文字也是一样分离出来,图片放在img文件里,文字放在fonts文件里,已在 module 中直接设置了
  5. 关于编译 React 时压缩到最小,在 config.json 中已设置了NODE_ENV=production,如果值不是production,会导致react压缩违法。
评论
发表评论
9个月前

web学习交流请与我联系

WRITTEN BY
娜娜娜娜
本人已懒到爆……
TA的新浪微博
PUBLISHED IN
reactJS

我竟然还会这个~

我的收藏