使用 Webpack 从零开始手动搭建 React 环境

新建一个项目的文件夹,打开终端,进入我们新建的文件夹目录,我们使用 npm init 来初始化一个 npm 项目,按照提示填写项目相关信息,然后它会根据你填的信息生成一个 package.json 文件。

我们的项目需要用到 Webpack 和 React,这里我们用 webpack 的版本 3.9.1,我们首先安装下这两个包:

npm i webpack@3.9.1 react

npm inpm install 的别名,其它 npm install 的别名有 isntall, addnpm install 的后缀的意思可以看 官方文档

npm install saves any specified packages into dependencies by default. Additionally, you can control where and how they get saved with some additional flags:

-P, –save-prod: Package will appear in your dependencies. This is the default unless -D or -O are present.

-D, –save-dev: Package will appear in your devDependencies.

-O, –save-optional: Package will appear in your optionalDependencies.

–no-save: Prevents saving to dependencies.

总结就是一句话,npm install 默认是把包添加到 package.json 文件的 dependencies 里,即会在开发和生产环境中都会用到,而加了 -D 就把包添加到 devDependencies 里,只会在开发中使用。至于另一个后缀 -S 应该是误用或者以往的用法,效果也是和默认一样,包会添加到 dependencies 里。

我们在项目跟目录下新建 build 文件夹,然后新建 webpack.config.js 文件,在这个文件中,我们写我们的 webpack 配置:

const path = require('path')

module.exports = {
  entry: {
    app: path.join(__dirname, '../client/app.js')
  },
  output: {
    filename: '[name].[hash].js',
    path: path.join(__dirname, '../dist'),
    publicPath: ''
  },
  module: {
    rules: [
      {
        test: /.jsx$/,
        loader: 'babel-loader'
      }
    ]
  }
}

publicPath 可以在引用生成的代码时在文件名前面加上 publicPath 的配置内容,通常用户设置 CDN 等。

我们用 babel-loader 这个 loader 来让 webpack 能处理 JSX:

npm i babel-core babel-loader -D

为了能支持 ES2015 和 React,我们在根目录下新建 .babelrc babel 的配置文件,内容如下:

{
  "presets": [
    ["es2015", { "loose": true }],
    "react"
  ]
}

上面的配置还需要安装如下包:

npm i babel-preset-es2015 babel-preset-es2015-loose babel-preset-react -D

然后我们在 package.json 文件 scripts 字段里新增如下命令:

"build": "webpack --config build/webpack.config.js"

在终端里运行 npm run build 就可以编译成功编译我们的代码了,打包完成的代码会放在根目录下的 dist 目录。

然后我们安装 html-webpack-plugin 插件来把我们 Webpack 打包后的 entry 下的所有文件都注入到一个生成的 HTML 页面里面,文件名字路径都是根据 output 的配置拼接而成。

npm i --save-dev html-webpack-plugin

然后在我们的 webpack.config.js 文件中加入以下内容:

const HTMLPlugin = require('html-webpack-plugin')

module.exports = {
  // ...
  plugins: [
    new HTMLPlugin()
  ]
}

这时我们再 npm run build 就会看到 dist 目录下生成了 index.html 文件,并且文件内引入了打包后的 JS 文件。

然后加入对 .js 结尾的文件的编译 babel-loader 配置,因为 node_modules 目录下的文件已经经过编译了,所以我们将这个目录排除:

// ...

module.exports = {
  // ...
  module: {
      // ...
      {
        test: /.js$/,
        loader: 'babel-loader',
        exclude: [
          path.join(__dirname, '../node_modules')
        ]
      }
    ]
  },
}

这时我们再次 npm run build,打开生成的 index.html 文件,就会看到正确的显示结果了。