官术网_书友最值得收藏!

Building with Webpack

Today, any modern client-side application represents a mix of many concerns that are addressed inpidually by various technologies. Addressing each concern inpidually simplifies the overall process of managing the project's complexity. The downside of this approach is that at some point in your project, you need to put together all the inpidual parts into one coherent application. Just like the robots in an automotive factory that assemble cars from inpidual parts, developers have something called as build-tools that assemble their projects from inpidual modules. This process is called the build process, and depending on the size and complexity of your project, it can take anywhere from milliseconds to hours to build.

Webpack will help us to automate our build process. First, we need to configure Webpack. Assuming you're in your ~/snapterest/ directory, create a new webpack.config.js file.

Now let's describe our build process in the webpack.config.js file. In this file, we'll create a JavaScript object that describes how to bundle our source files. We want to export that configuration object as a Node.js module. Yes, we'll treat our webpack.config.js file as a Node.js module. To do this, we'll assign our empty configuration object to a special module.exports property:

const path = require('path'); 
module.exports = {};

The module.exports property is a part of the Node.js API. It's a way of telling Node.js that whenever someone imports our module they will get access to that object. So what should this object look like? This is where I recommend that you to take a look at Webpack's documentation and read about the core concepts of Webpack, from the following link: https://webpack.js.org/concepts/

The first property of our configuration object will be the entry property:

module.exports = {
  entry: './source/app.js',
};

As the name suggests, the entry property describes the entry point to our web application. In our case, the value for this property is ./source/app.js—this is the first file that starts our application.

The second property of our configuration object will be the output property:

output: {
  path: path.resolve(__dirname, 'build'),
  filename: 'snapterest.js'
},

The output property tells Webpack where to output the resulting bundle file. In our case, we're saying that we want the resulting bundle file to be called snapterest.js and it should be saved to the ./build directory.

Webpack treats every source file as a module, which means all our JavaScript source files will be treated as modules that Webpack will need to bundle together. How do we explain this to Webpack?

We do this with the help of the third property of our configuration object called module:

module: {
  rules: [
    {
      test: /\.js$/,
      use: [
        {
          loader: 'babel-loader',
          options: {
            presets: ['react', 'latest'],
            plugins: ['transform-class-properties']
          }
        }
      ],
      exclude: path.resolve(__dirname, 'node_modules')
    }
  ]
}

As you can see, our module property gets an object as its value. This object has a single property called rules—an array of rules where each rule describes how to create Webpack modules from different source files. Let's take a closer look at our rules.

We have a single rule that tells Webpack how to handle our source JavaScript files:

{
  test: /\.js$/,
  use: [
    {
      loader: 'babel-loader',
      options: {
        presets: ['react', 'latest'],
        plugins: ['transform-class-properties']
      }
    }
  ],
  exclude: path.resolve(__dirname, 'node_modules')
}

This rule has three properties: test, use, and exclude. The test property tells Webpack which files this rule applies to. It does this by matching our source file names against the RegEx expression that we specified as a value for our test property: /\.js$/. If you're familiar with RegEx, then you'll recognise that /\.js$/ will match all filenames that end with .js. This is exactly what we want: to bundle all our JavaScript files.

When Webpack finds and loads all source JavaScript files, it tries to interpret them as plain JavaScript files. However, our JavaScript files won't be plain JavaScript files, instead they will have ECMAScript 2016 syntax, as well as React-specific syntax.

How can Webpack understand all that nonplain JavaScript syntax? With the help of Webpack loaders we can transform nonplain JavaScript syntax in to plain JavaScript. A Webpack loader is a transformation applied to a source file. Our use property describes a list of transformations that we want to apply:

use: [
  {
    loader: 'babel-loader',
    options: {
      presets: ['react', 'latest'],
      plugins: ['transform-class-properties']
    }
  }
],

We have one transformation that is responsible for transforming our React-specific syntax and ECMAScript 2016 syntax into plain JavaScript:

{
  loader: 'babel-loader',
  options: {
    presets: ['react', 'latest'],
    plugins: ['transform-class-properties']
  }
}

Webpack transformations are described with objects that have the loader and options properties. The loader property tells Webpack which loader performs the transformation, and the options property tells it which options should be passed to that loader. The loader that will transform our ECMAScript 2016 and React-specific syntaxes in to plain JavaScript is called babel-loader. This specific transformation process is called transpilation or source-to-source compilation—it takes source code written in one syntax and transforms it into a source code written in another syntax. We're using one of the most popular JavaScript transpilers today, called Babel: https://babeljs.io. Webpack has a Babel loader that uses Babel transpiler to transform our source code. Babel loader comes as a separate Node.js module. Let's install this module and add it to the list of our development dependencies. Assuming you're in your ~/snapterest/ directory, run this command:

npm install babel-core babel-loader --save-dev

The options property of our Webpack loader has a couple of Babel presents: latest and react and a Babel transform-class-properties plugin:

options: {
  presets: ['react', 'latest'],
  plugins: ['transform-class-properties']
}

These are Babel plugins that transpile different syntaxes: the latest plugin transpiles the syntaxes of ECMAScript 2015, ECMAScript 2016, and ECMAScript 2017 to old JavaScript syntax, and the react plugin transpiles React-specific syntax to plain JavaScript syntax, while the transform-class-properties plugin transpiles class properties.

These Babel plugins are distributed as standalone Node.js modules, which we need to install separately. Assuming you're in your ~/snapterest/ directory, run the following command:

npm install babel-preset-latest babel-preset-react babel-plugin-transform-class-properties --save-dev

Finally, we have the third property in our Webpack rule called exclude:

exclude: path.resolve(__dirname, 'node_modules')

This property tells Webpack to exclude the node_modules directory from our transformation process.

Now we have our webpack.config.js file ready. Before we run our bundling process for the first time, let's add a new script called start to our package.json file:

"scripts": {
  "start": "webpack -p --config webpack.config.js",
  "test": "echo \"Error: no test specified\" && exit 1"
},

Now if you run npm run start or npm start, npm will run the webpack -p --config webpack.config.js command. This command runs Webpack that bundles our source files for production using the webpack.config.js file.

We're ready to bundle our source files! Navigate to your ~/snapterest/ directory and run this command:

npm start

In the output, you should see the following:

Version: webpack 2.2.1
Time: 1151ms
 Asset Size Chunks Chunk Names
app.js 519 bytes 0 [emitted] main
 [0] ./source/app.js 24 bytes {0} [built]

More importantly, if you check your project's ~/snapterest/build/ directory, you'll notice that it now has the snapterest.js file with some code already inside of it—that's our (empty) JavaScript application with some Node.js modules that are ready to run in a web browser!

主站蜘蛛池模板: 淳安县| 鹿泉市| 永川市| 佛冈县| 义马市| 襄垣县| 鹿邑县| 论坛| 容城县| 蕉岭县| 桃园市| 邵武市| 荣昌县| 晋州市| 汪清县| 南京市| 青川县| 汉阴县| 临汾市| 寿宁县| 雷州市| 丹棱县| 昭觉县| 阜新| 南开区| 延吉市| 苍梧县| 甘孜县| 巴南区| 上犹县| 唐山市| 台江县| 邛崃市| 古丈县| 济宁市| 松阳县| 额济纳旗| 忻州市| 庆城县| 安远县| 赤水市|