diff --git a/docs/designers-developers/developers/tutorials/javascript/js-build-setup.md b/docs/designers-developers/developers/tutorials/javascript/js-build-setup.md index 067e99e5790f2..ebd65dc6a232d 100644 --- a/docs/designers-developers/developers/tutorials/javascript/js-build-setup.md +++ b/docs/designers-developers/developers/tutorials/javascript/js-build-setup.md @@ -8,10 +8,12 @@ Most browsers can not interpret or run ESNext and JSX syntaxes, so we use a tran There are a few reasons to use ESNext and the extra step. First, it makes for simpler code that is easier to read and write. Using a transformation step allows for tools to optimize the code to work on the widest variety of browsers. Also, by using a build step you can organize your code into smaller modules and files that can be bundled together into a single download. -There are many tools that can perform this transformation or build step, but in this tutorial we will focus on Webpack and Babel. +There are different tools that can perform this transformation or build step, but WordPress uses Webpack and Babel. [Webpack](https://webpack.js.org/) is a pluggable tool that processes JavaScript creating a compiled bundle that runs in a browser. [Babel](https://babeljs.io/) transforms JavaScript from one format to another. You use Babel as a plugin to Webpack to transform both ESNext and JSX to JavaScript. +The [@wordpress/scripts](https://www.npmjs.com/package/@wordpress/scripts) package abstracts these libraries away to standardize and simplify development, so you won't need to handle the details for configuring those libraries. + ## Quick Start For a quick start, you can use one of the examples from the [Gutenberg Examples repository](https://github.com/wordpress/gutenberg-examples/). Each one of the `-esnext` directories contain the necessary files for working with ESNext and JSX. @@ -38,6 +40,7 @@ To start a new node project, first create a directory to work in. ``` mkdir myguten-block +cd myguten-block ``` You create a new package.json running `npm init` in your terminal. This will walk you through creating your package.json file: @@ -48,7 +51,7 @@ npm init package name: (myguten-block) myguten-block version: (1.0.0) description: Test block -entry point: (index.js) block.js +entry point: (index.js) build/index.js test command: git repository: keywords: @@ -76,76 +79,23 @@ Is this OK? (yes) yes The next step is to install the packages required. You can install packages using the npm command `npm install`. If you pass the `--save-dev` parameter, npm will write the package as a dev dependency in the package.json file. The `--save-exact` parameter instructs npm to save an exact version of a dependency, not a range of valid versions. See [npm install documentation](https://docs.npmjs.com/cli/install) for more details. -Run `npm install --save-dev --save-exact webpack webpack-cli` +Run `npm install --save-dev --save-exact @wordpress/scripts` -After installing, a `node_modules` directory is created with the webpack module and its dependencies. +After installing, a `node_modules` directory is created with the modules and their dependencies. Also, if you look at package.json file it will include a new section: ```json "dependencies": { - "webpack": "4.29.0" + "@wordpress/scripts": "3.1.0" } ``` ## Webpack & Babel -Next, we will configure webpack to process the `block.js` file and run babel to transform the JSX within it. - -Create the file `webpack.config.js` - -```js -// sets mode webpack runs under -const NODE_ENV = process.env.NODE_ENV || 'development'; - -module.exports = { - mode: NODE_ENV, - - // entry is the source script - entry: './block.js', - - // output is where to write the built file - output: { - path: __dirname, - filename: 'block.build.js', - }, - module: { - // the list of rules used to process files - // this looks for .js files, exclude files - // in node_modules directory, and uses the - // babel-loader to process - rules: [ - { - test: /.js$/, - exclude: /node_modules/, - loader: 'babel-loader', - }, - ], - }, -}; -``` - -Next, you need to install babel, the webpack loader, and the JSX plugin using: - -`npm install --save-dev --save-exact babel-loader @babel/core @babel/plugin-transform-react-jsx` - -You configure babel by creating a `.babelrc` file: - -```json -{ - "plugins": [ - [ "@babel/plugin-transform-react-jsx", { - "pragma": "wp.element.createElement" - } ] - ] -} -``` - -This pragma setting instructs Babel that any JSX syntax such as `` should be transformed into `wp.element.createElement( Hello )`. The name of the setting (`transform-react-jsx`) is derived from the fact that it overrides the default assumption to transform to `React.createElement( Hello )`. - -With both configs in place, you can now run webpack. +The `@wordpress/scripts` package handles the dependencies and default configuration for Webpack and Babel. The scripts package expects the source file to compile to be found at `src/index.js`, and will save the compiled output to `build/index.js`. -First you need a basic block.js to build. Create `block.js` with the following content: +With that in mind, let's set up a basic block. Create a file at `src/index.js` with the following content: ```js const { registerBlockType } = wp.blocks; @@ -154,12 +104,8 @@ registerBlockType( 'myguten/test-block', { title: 'Basic Example', icon: 'smiley', category: 'layout', - edit() { - return
Hola, mundo!
; - }, - save() { - return
Hola, mundo!
; - }, + edit: () =>
Hola, mundo!
, + save: () =>
Hola, mundo!
, } ); ``` @@ -167,71 +113,47 @@ To configure npm to run a script, you use the scripts section in `package.json` ```json "scripts": { - "build": "webpack" + "build": "wp-scripts build" }, ``` You can then run the build using: `npm run build`. -After the build finishes, you will see the built file created at `block.build.js`. +After the build finishes, you will see the built file created at `build/index.js`. ## Finishing Touches ### Development Mode -The basics are in place to build. You might have noticed the webpack.config.js sets a default mode of "development". Webpack can also run in a "production" mode, which shrinks the code down so it downloads faster, but makes it difficult to read. +The **build** command in `@wordpress/scripts` runs in a "production" mode. This shrinks the code down so it downloads faster, but makes it difficult to read in the process. You can use the **start** command which runs a development mode that does not shrink the code, and additionally continues a running process to watch the source file for more changes and rebuild as you develop. -The mode is setup so it can be configured using environment variables, which can be added in the scripts section of `package.json`. +The start command can be added to the same scripts section of `package.json`: ```json "scripts": { - "dev": "webpack --watch", - "build": "cross-env NODE_ENV=production webpack" + "start": "wp-scripts start", + "build": "wp-scripts build" }, ``` -This sets the environment variables, but different environments handle these settings in different ways. Using the `cross-env` helper module can help to handle this. Be sure to install the `cross-env` package using `npm install --save-dev --save-exact cross-env`. - -Additionally, webpack has a `--watch` flag that will keep the process running, watching for any changes to the `block.js` file and re-building as changes occur. This is useful during development, when you might have a lot of changes in progress. - -You can start the watcher by running `npm run dev` in a terminal. You can then edit away in your text editor; after each save, webpack will automatically build. You can then use the familiar edit/save/reload development process. +Now, when you run `npm run start` a watcher will run in the terminal. You can then edit away in your text editor; after each save, it will automatically build. You can then use the familiar edit/save/reload development process. **Note:** keep an eye on your terminal for any errors. If you make a typo or syntax error, the build will fail and the error will be in the terminal. -### Babel Browser Targeting - -Babel has the ability to build JavaScript using rules that target certain browsers and versions. By setting a reasonable set of modern browsers, Babel can optimize the JavaScript it generates. - -WordPress has a preset default you can use to target the minimum supported browsers by WordPress. - -Install the module using: `npm install --save-dev --save-exact @wordpress/babel-preset-default` - -You then update `.babelrc` by adding a "presets" section: - -``` -{ - "presets": [ "@wordpress/babel-preset-default" ], - "plugins": [ - [ "@babel/plugin-transform-react-jsx", { - "pragma": "wp.element.createElement" - } ] - ] -} -``` ### Source Control Because a typical `node_modules` folder will contain thousands of files that change with every software update, you should exclude `node_modules/` from your source control. If you ever start from a fresh clone, simply run `npm install` in the same folder your `package.json` is located to pull your required packages. -Likewise, you do not need to include `node_modules` or any of the above configuration files in your plugin because they will be bundled inside the file that webpack builds. **Be sure to enqueue the `block.build.js` file** in your plugin PHP. This is the only JavaScript file needed for your block to run. +Likewise, you do not need to include `node_modules` or any of the above configuration files in your plugin because they will be bundled inside the file that webpack builds. **Be sure to enqueue the `build/index.js` file** in your plugin PHP. This is the only JavaScript file needed for your block to run. ## Summary -Yes, the initial setup is rather tedious, and there are a number of different tools and configs to learn. However, as the quick start alluded to, copying an existing config is the typical way most people start. +Yes, the initial setup is a bit more involved, but the additional features and benefits are usually worth the trade off in setup time. With a setup in place, the standard workflow is: - Install dependencies: `npm install` -- Start development builds: `npm run dev` +- Start development builds: `npm run start` - Develop. Test. Repeat. - Create production build: `npm run build`