parcel 最大的特色就是简单,内置常见依赖,默认支持模块热替换和引用 CSS 文件。css
webpack 4.0 在优化构建性能的同时,也添加了许多默认配置。(重大变化:点我)html
特性 | webpack | parcel |
---|---|---|
文件名添加 hash | 支持 | 不支持 |
构建时处理 css | 需配置 | 易 |
tree-shaking | production 下支持 | 不支持 |
构建时预编译 | production 下支持 | 不支持 |
生成 html 文件并引用资源 | 需配置,且默认 CSS 在 JS 文件中 | 自动生成,CSS 是独立的文件 |
热模块更新(HMR) | 需配置 | 开发模式下默认开启 |
如下针对构建工具经常使用功能,对 webpack
和 parcel
进行对比node
const path = require('path'); module.exports = { mode: 'development', // development / production entry: './src/index.js', output: { filename: 'bundle-[hash].js', path: path.resolve(__dirname, 'dist') } };
两个模式(主要区别就是前一个开发模式不压缩,生产模式压缩)react
NamedModulesPlugin
UglifyJsPlugin
, ModuleConcatenationPlugin(预编译)
and NoEmitOnErrorsPlugin
开发模式(支持热更新,并开启服务):webpack
parcel index.html --out-dir ../dist/
生产模式(代码压缩):es6
parcel build index.js --out-dir ../dist
webpack 只构建 JS 文件,因此 CSS 文件都会以字符串形式保存在 JS 文件中(固然必要时也能够单独配置,拆分 css 文件),并需手动引用到 index.html 文件中。web
对 CSS 预处理,都须要配置 webpack.config.js 文件,添加 loadertypescript
module: { rules: [{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] }] }
在 js 文件中引入的 CSS 会自动构建并引用到 html 里,还支持预处理器如:less sass stylusnpm
这里举 sass 为例json
npm install node-sass
import './index.sass'
执行 parcel,sass 文件将会被构建成 css 文件名引用到 index.html 中
babel
安装依赖包
npm install babel-loader babel-core babel-preset-env webpack
配置 webpack.config.js
文件
module: { rules: [{ test: /\.js$/, exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', options: { presets: ['babel-preset-env'] } } }] }
postcss
安装
npm i -D postcss-loader
配置 postcss.config.js
文件
module.exports = { parser: false, plugins: { 'postcss-import': {}, 'postcss-cssnext': {}, 'cssnano': {}, 'autoprefixer': true } }
typescript
安装依赖包
npm install --save-dev typescript ts-loader
建立 tsconfig.json
文件
{ "compileOptions": { "outDir": "./dist/", "noImplicitAny": true, "module": "es6", "target": "es5", "jsx": "react", "allowJs": true } }
建立 index.ts
文件
function greeter(person: string) { return "Hello, " + person; } let user = "Jane User"; document.body.innerHTML = greeter(user);
配置 webpack.config.js
const path = require('path'); module.exports = { mode: 'development', entry: './src/index.ts', module: { rules: [{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] }, { test: /.tsx?$/, use: 'ts-loader', exclude: /node_modules/ }] }, resolve: { extensions: [ '.tsx', '.ts', '.js' ] }, output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') }, };
babel
npm i babel-preset-env // create a .babelrc: { "presets": ["env"] }
PostCSS
npm i postcss-modules autoprefixer { "plugins": { "autoprefixer": { "grid": true } } }
typescript
只需安装 typescript 便能使用
npm i typescript
有三种方法来实现
在 webpack.config.js
中配置 entry point
const path = require('path'); const HTMLWebpackPlugin = require('html-webpack-plugin'); module.exports = { mode: 'development',//'production', entry: { index: './src/index.js', another: './src/util.js' }, plugins: [ new HTMLWebpackPlugin({ // 生成 html 文件,并引入入口文件 title: 'Code Splitting' }) ], output: { filename: '[name].bundle.js', path: path.resolve(__dirname, 'dist') }, };
使用 splitChunks
提取公共组件
webpack 4
中,CommonChunkPlugin
将被配置项 optimization.splitChunks
const path = require('path'); const HTMLWebpackPlugin = require('html-webpack-plugin'); module.exports = { mode: 'development', entry: { index: './src/index.js', another: './src/another.js' }, plugins: [ new HTMLWebpackPlugin({ // 生成 html 文件,并引入入口文件 title: 'Code Splitting' }) ], optimization: { splitChunks: { chunks: "all", name: 'common', } }, output: { filename: '[name].bundle.js', path: path.resolve(__dirname, 'dist') }, };
动态引用,import
异步加载
异步加载文件,并返回 promise
,若是多个异步import
的 chunkname
一致,则构建时会合并这个文件
配置 webpack.config.js
const path = require('path'); const HTMLWebpackPlugin = require('html-webpack-plugin'); module.exports = { mode: 'development',//'production', entry: { index: './src/index.js', another: './src/another.js' }, output: { filename: '[name].bundle.js', chunkFilename: '[name].bundle.js', path: path.resolve(__dirname, 'dist') }, };
引用方法
function getComponent() { return import(/* webpackChunkName: "lodash" */ 'lodash').then(_ => { // todo }) } getComponent().then(component => {})
async
写法
async function getComponent() { const _ = await import(/* webpackChunkName: "lodash" */ 'lodash'); // todo } getComponent().then(component => {});
util.js
文件
export function a() { console.log('a'); } export function b() { console.log('b'); }
index.js
文件
import('./util').then(function (util) { util.a(); });
安装依赖
npm install --save-dev webpack-dev-server
配置 webpack.config.js
const path = require('path'); const HTMLWebpackPlugin = require('html-webpack-plugin'); const webpack = require('webpack'); module.exports = { mode: 'development',//'production', entry: { index: './src/index.js', another: './src/another.js' }, devServer: { contentBase: './dist', hot: true }, plugins: [ // new CleanWebpackPlugin(['dist']), new HTMLWebpackPlugin({ title: 'Hot Module Replacement' }), new webpack.NamedModulesPlugin(), new webpack.HotModuleReplacementPlugin() ], output: { filename: '[name].bundle.js', chunkFilename: '[name].bundle.js', path: path.resolve(__dirname, 'dist') }, };
配置 package.json
"scripts": { "start": "webpack-dev-server --open" }
执行运行代码
npm start
开发模式下自动默认支持