This article mainly introduces the Webpack automated construction practice guide. The editor thinks it is quite good. Now I will share it with you and give it as a reference. Let’s follow the editor and take a look.
Since the current blog is built using wordpress, I have to modify some codes frequently, but modifying third-party source code is really painful, so I decided to start using React Node.js / Python develops new blog projects and eventually replaces the current blog code, which facilitates future blog maintenance and updates. It also enables self-development of technology, architecture design, and problem-solving abilities to be improved. At the same time, the entire development process is recorded, summarized, and shared. I hope to Make progress together with readers. This article introduces how to use Webpack, Babel, Eslint, documentation.js, etc. to build a project development environment and production environment. It is also considered as the preparation work of the project. The next issue plans to introduce the project's architectural design and technology stack selection.
npm VS Yarn
In this project we use Yarn to manage the project's three-party dependencies, but don't worry, Yarn does not conflict with NPM, nor is it intended to replace NPM. The usage is basic Consistent, just need to briefly understand the following points.
Three-party library version management
Both npm and Yarn use package.json to track project dependencies. The version number is not always accurate because you can define the version number range. Different update scopes of npm may cause different versions of packages to be installed on machines with the same package.json file, which may cause some different exceptions and conflicts.
Does npm have a solution? In npm, you can use npm shrinkwrap to generate a version lock file npm-shrinkwrap.json. When npm install, this file will be read before reading package.json. However, when the package version is updated, the version lock file will not be automatically updated. , we have to manually execute the npm shrinkwrap command again to update it.
So what are the advantages of Yarn? Every time an installation library package is added or updated, Yarn will create (or update) the yarn.lock file. This ensures that all machines install the same version package and supports the allowed version range defined in package.json. The difference between Yarn and npm is that Yarn yarn.lock will always be updated automatically, while npm needs to be updated manually.
Concurrent installation
npm usually installs dependencies one by one in order, while Yarn supports parallel loading and installation of multiple third-party library packages, all of which are faster and more efficient. .
Offline cache
When using Yarn management package, the third-party library package is stored on the local disk. The next installation will directly use the local file instead of downloading it again. This also starts from On the other hand, its installation speed is better than npm.
In short, Yarn and npm are used in almost the same way, but its version management is more convenient, the installation speed is faster, and it has more advantages. However, in fact, all its third-party library package loading addresses and npm are the same. is unified.
Webpack
We use the Webpack packaging tool as the automated construction tool for the project, and treat JavaScript, CSS, images and other resources as JavaScript modules (use Webpack loader to process the conversion ) for unified management. About Webpack bloggers have summarized two articles before, you can refer to:
Webpack builds SPA application development environment
Webpack Modular management of resources such as CSS and images
With the foreshadowing of the previous article, this article does not intend to introduce the working principle and specific configuration of Webpack, but plans to develop and test it from the project practice, packaging Think about how to better organize Webpack, how to use Webpack to improve project development and packaging efficiency.
Webpack configuration file
First we create webpack.config.js
Configuration file in the root directory:
module.exports = function () { let env let _DEV_ = true // 开发环境 let _PROD_ = false // 生产环境 switch (process.env.NODE_ENV) { case 'dev': env = 'dev' _DEV_ = true _PROD_ = false break case 'production': env = 'prod' _DEV_ = false _PROD_ = true break default: env = 'dev' _DEV_ = true _PROD_ = false } // 根据环境参数动态决定引入对应配置文件 return require(`./webpack/${env}.conf.js`)({ ROOTPATH: __dirname, _DEV_, _PROD_ }) }
According to The process.env.NODE_ENV environment parameter dynamically determines the loading of the corresponding configuration file:
dev: loads the webpack/env.conf.js configuration file;
prod: Load the webpack/prod.conf.js configuration file;
We created the webpack directory in the project root directory, and created three configuration files in it:
base.conf.js: Basic configuration file, configuration required in both development and production environments;
dev.conf.js: Development environment configuration file ;
prod.conf.js: Production environment packaging configuration file;
Development environment configuration
The development environment configuration file defines some build configurations for development, then introduces the basic configuration file, uses the webpack-merge third-party library, merges the development environment configuration into the basic configuration object, and then returns to the development environment to package the build configuration object as Webpack Package and build parameters:
const webpackMerge = require('webpack-merge') const PUBLICPATH = '/assets/' const PORT = '9090' let options = { /* ... */ } module.exports = function (args) { options.ROOTPATH = args.ROOTPATH options.env = args.env return webpackMerge(require('./base.conf')(options), { devtool: 'source-map', devServer: { contentBase: path.join(args.ROOTPATH, './src'), historyApiFallback: true, inline: true, hot: true, port: PORT, proxy: { '*': `http://localhost:${PORT}/${PUBLICPATH}/` } }, plugins: [] }) }
Production environment configuration
The production environment configuration file defines the build configuration used in the production environment, and then also introduces the basic configuration file. Use the webpack-merge third-party library to merge the production environment configuration into the basic configuration, and then return the configuration object as a parameter for the Webpack packaging build:
let options = { /* ... */} module.exports = function (args) { options.ROOTPATH = args.ROOTPATH options.env = args.env return webpackMerge(require('./base.conf')(options), { plugins: [ new webpack.DefinePlugin({ 'process.env': 'production' }), // 生成独立css文件 new ExtractTextPlugin({ filename: 'css/[name].css' }), new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false } }) ] }) }
Instruction
Then there is To configure executable instructions for different environments, we use npm scripts to configure execution instructions in the package.json file:
{ "scripts": { "start": "cross-env NODE_ENV=dev webpack-dev-server", "build": "cross-env NODE_ENV=production webpack" } }
start:开发环境运行指令,使用cross-env三方库设置process.env.NODE_ENV为dev,并在本地开启webpack开放服务器,方便开放;
build:生产环境运行指令,使用cross-env三方库设置process.env.NODE_ENV为production,将打包输出代码和资源文件;
最后分别执行yarn start和yarn build指令即可分别执行开发和生产构建打包了。
Babel
可自定义配置型的通用编译器,需要明确指定期望babel做什么,通过安装插件(plugins)或预设(presets,也就是一组插件)来指示 Babel 去做什么事情。
配置文件
首先需要创建一个配置文件,即在项目的根路径下创建 .babelrc 文件。然后输入以下内容作为开始:
{ "presets": [], "plugins": [] }
之后就可以拓展这个配置文件以指定此项目中 Babel 的功能。
babel-preset-es2015
我们期望在项目中能使用更新潮的ES6版本语法,但由于目前还有许多JavaScript环境不能很好兼容ES6,所以需要Babel将ES6代码编译成ES5语法代码,保证应用的使用范围。
执行如下命令,安装 “es2015” Babel 预设:
yarn add --dev babel-preset-es2015
修改.babelrc配置文件:
{ "presets": [ "es2015" ], "plugins": [] }
babel-preset-stage-num
另外,JavaScript还有一些提案,正在推进,不久的将来也可能成为标准的一部分,所以目前将这些草案提出,内容更新直至最终成为标准,添加进标准库的过程划分为 5(0-4)个阶段。 根据提案的状态和内容,将其在各个阶段更新(阶段0至阶段3),最终在阶段 4表明该提案被标准正式采纳,当然不被采纳的提案不会进入阶段4。
以下是4个不同阶段的打包预设:
babel-preset-stage-0
babel-preset-stage-1
babel-preset-stage-2
babel-preset-stage-3
注: stage-4 预设不存在,它其实就是上文介绍的 es2015 预设。
以上每种预设都包含紧随的后期阶段预设,同时还可能包含其他额外特性。例如,babel-preset-stage-0 包含 babel-preset-stage-1, babel-preset-stage-2,babel-preset-stage-3,而 babel-preset-stage-1则包含 babel-preset-stage-2,babel-preset-stage-3依次后推。
点此查看关于各阶段预设的详细特性内容文档
我们次选择支持特性最全面的预设:
yarn add --dev babel-preset-stage-0
在.babelrc 配置文件内添加:
{ "presets": [ "es2015", "stage-0" ], "plugins": [] }
babel-preset-react
我们的项目期望使用React开发,所以需要拓展支持React/JSX语法,安装预设:
yarn add --dev babel-preset-react
.babelrc 配置文件内添加:
{ "presets": [ "es2015", "stage-0", "react" ], "plugins": [] }
babel-polyfill
至此,使用Babel,我们的·项目几乎可以支持所有的ES6及ES7语法,但是对于新增的JavaScript API是无能为力的,如Symbol这种新API,并不是通过语法转换能实现的,所以我们需要另外的方式解决。
业内提出了Polyfill(填充),以添加额外代码的方式使得当前运行环境支持不存在的原生Api ,拓展了尚处在推进阶段的API的使用范围。
yarn add babel-polyfill
此处不需要添加--dev参数。
然后在文件入口引入即可:
import "babel-polyfill";
babel-runtime
前面提到的Babel通过转换语法以支持我们以ES6等更新的语法方式开发代码,这时Babel会在每一个处理的文件头部注入辅助代码,会产生很多冗余,重复性的内容,导致代码量暴增,所以我们需要将这些辅助代码抽取至一个统一环境,Babel提供的就是运行时(runtime)环境。
要实现Babel运行时环境,需要安装 babel-plugin-transform-runtime 和 babel-runtime
:
yarn add --dev babel-plugin-transform-runtime babel-runtime
然后更新 .babelrc:
{ "plugins": [ "transform-runtime", ] }
按需加载(babel-plugin-import)
很多时候,我们开发业务并不需要自制UI,会选择一些开源组件库以快速开发实现产品,如antd,weui,material-ui等,我们可以选择直接提前加载三方库所有模块,但是很多时候我们希望能实现按需加载,减少初始代码包的体积,这时,我们可以在babel配置文件中声明按需加载该第三方库,当然首先得安装插件babel-plugin-import
:
yarn add --dev babel-plugin-import
然后在配置文件.babelrc中添加配置:
{ "plugins": [ "import", { "style": "../styles", // 加载样式解析方式,(值为true时,可能是less/Sass),此处值设为相对libraryName具体模块请求路径值 "libraryDirectory": "", // 加载包的目录,(默认是lib,即node_modules/lib/) "libraryName": "material-ui" // 加载三方组件库名,当然另外需要安装该三方库 } ] }
此时,webapck loader处理css时不能添加exclude: /node_modules/。
其他插件
我们还可以根据项目实际需求和爱好自定义安装插件,更多信息查看官方插件文档。
在这里推荐一款babel-pliugin-transform-s2015-classes插件拓展以实现JavaScript内置class对象的extends继承特性,参考文档ES2015 classes transform。
yarn add --dev babel-plugin-transform-es2015-classes
在.babelrc文件内添加plugins内容:
{ "plugins": [ "transform-runtime", "transform-es2015-classes", [ "import", { "style": "css", "libraryDirectory": "", "libraryName": "material-ui" } ] ] }
语法检测(Eslint)
为了保证代码质量,统一代码风格是很重要的,而只靠团队口头约定明显是不能尽如人意,所以通常需要在自动化构建层面进行代码语法检测,有很多语法检测工具如jslint,eslint,目前使用率最高的要数eslint了,所以我们的项目也引入eslint,首先安装依赖:
yarn add --dev eslint
更多细节参考配置文档,下文简要介绍主要。
配置文件
然后在项目根目录下建立eslint配置文件.eslintrc,内容是一个对象:
{}
解析器(parser)
另外,ESLint 默认使用Espree作为其解析器,你可以在配置文件中指定一个不同的解析器,如babel-eslint,esprima等,我们项目使用babel-eslint:
yarn add --dev babel-eslint
在配置文件内添加parser属性:
{ "parser": "babel-eslint" }
eslint-plugin-babel
eslint还支持可选安装插件,拓展eslint,如eslint-plugin-babel,该插件与babel-eslint协作,使得eslint可以更好的与babel同时工作,更多请查看参考文档。
yarn add --dev eslint-plugin-babel
在配置文件添加声明:
{ "plugins": [ "babel" ], }
aslant-plugin-react
eslint默认是检测JavaScript语言语法的,而对于React/JSX这类包含其自定义语法和语法糖的框架而言,需要另外拓展安装插件才能和eslint结合使用,所以使用eslint检测React特定语法需要安装eslint-plugin-react插件:
yarn add --dev eslint-plugin-react
添加配置文件:
{ "plugins": [ "babel", "react" ] }
拓展(extends)
除了自定义语法检查规则外,我们可以使用Eslint提供的集成拓展包,使用共享的语法检测配置对象,如eslint-config-standard和eslint-config-standard-react:
yarn add --dev eslint-config-standard eslint-config-standard-react eslint-plugin-standard eslint-plugin-promise eslint-plugin-import eslint-plugin-node eslint-plugin-react
注:这里包含了上一小节提到的eslint-plugin-react是为了支持eslint-config-standard-react配置包。
然后在.eslintrc配置文件中添加拓展:
{ "extends": [ "standard", "standard-react" ] }
若不想使用这类集成语法检测规则,可以移除配置文件中内容并移除依赖:
yarn remove eslint-config-standard eslint-config-standard-react eslint-plugin-standard eslint-plugin-promise eslint-plugin-import eslint-plugin-node eslint-plugin-react
语法规则(rules)
要添加语法规则,只需要声明在rules属性对象中,如:
{ "rules": { "strict": 0, "semi": 2, // 强制语句末尾添加符号,否则报错 "quotes": [ 1, "single" ], } }
规则结构
当声明语法检测规则时,需要设置规则 ID为以下值之一:
"off" 或 0 – 关闭规则
"warn" 或 1 – 开启规则,使用警告级别的错误:warn (不会导致程序退出)
"error" 或 2 – 开启规则,使用错误级别的错误:error (当被触发的时候,程序会退出)
{ "rules": { eqeqeq: 0, // or "off" curly: 2 // or "error" } }
某些规则还可能有额外的配置选项,可以使用数组指定,如:
{ "rules": { "eqeqeq": "off", "curly": "error", "quotes": ["warn", "single"] // 开启使用单引号,若使用双引号将发出警告 } }
指令
要执行语法检测,只需要执行./node_modules/.bin/eslint src(项目本地安装eslint,而非全局安装,则需要指定执令脚本路径),将会遍历检查src目录下的所有源码文件语法并输出结果,当然我们最终需要将指令根据npm scripts规范插入package.json文件:
{ "scripts": { "lint": "eslint --cache --fix src" } }
使用npm scripts执行指令时,无论项目本地安装还是全局安装,都可以省略指令脚本路径,因为npm将自动匹配可用路径。
文档
一个优秀的项目当然少不了文档,文档可以帮助其他开发者快速了解整个项目内容及进度,也有助于bug修复时查找内容,追踪溯源,所以文档是有必要的,于是通过调研发现了JSdoc和documentation.js帮助自动化产出API文档。
documentation
和JSdoc一样,documentation也是根据代码注释自动构建出项目文档,前提是我们的代码注释必须按照其规范指南,详情参考JSdoc文档。
我们首先安装documentation.js:
yarn add --dev documentation
指令
然后可以执行指令:
./node_modules/.bin/documentation build src/app.js -f md > API.md
会发现在根目录输出了API.md文件。
我们在package.json文件中配置npm scripts执行脚本:
"scripts": { "doc": "./node_modules/.bin/documentation build src/app.js -f md > API.md" }
项目本地安装documentation时,直接在命令行终端执行指令时需要指定./node_modules/.bin/documentation路径,若全局安装则只可直接使用documentation指令。而执行package.json中的脚步,可以直接简写,npm将为我们自动匹配。
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
利用vue.js如何实现$refs和$emit 父子组件交互
The above is the detailed content of About automated builds in Webpack (detailed tutorial). For more information, please follow other related articles on the PHP Chinese website!