Webpack new features
- Persistent cache
- ModuleIds & chunkIds optimization
- More intelligent Tree shaking
- Module Federation
- .
New features for Vue3
- smaller
- faster
- Enhance TypeScript support
- Strengthen API design consistency
- Improve their maintainability
- Open up more low-level functionality
Start the configuration
Create a project
npm init -y
Install required plug-ins and necessary configurations
- Install webppack5
npm i webpack webpack-cli webpack-dev-server -D
Copy the code
- CSS analytical
npm i less less-loader css-loader style-loader -D
Copy the code
- vue-loader
npm i vue-loader@next @vue/compiler-sfc -D
Copy the code
Add the shims-vue.d.ts file to the SRC folder to resolve vUE type errors
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
Copy the code
- The template parsing
npm i html-webpack-plugin -D
Copy the code
- Install typescript and parse plug-ins
npm i typescript ts-loader --save-dev
Copy the code
- Handle image url-loader
npm i url-loader -D
Copy the code
- Handle CSS, less
cnpm i mini-css-extract-plugin css-loader less less-loader postcss postcss-loader -D
Copy the code
The configuration is shown in webpack.base.config.js
- To deal with ts
npm i typescript ts-loader --save-dev
Copy the code
Ts-loader performs type check and translation for a single process. Therefore, the efficiency is slow. You can use the multi-process solution: Disable type check for TS-Loader, and the type check is performed by the fork-ts-checker-webpack-plugin. npm i fork-ts-checker-webpack-plugin –save-dev
- Other plug-ins
Merge plug-in configuration Webpack-Merge
Remove the dist package clean-webpack-plugin generated by Build
Cross-platform cross – env
Create a configuration file and write the configuration (webpack4 is basically the same as webpack5)
Create the build folder, and then create the public configuration file webpack.base.config.js, development configuration file webpack.dev.config.js, and production configuration file webpack.prod.config.js.
webpack.base.config.js
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const {VueLoaderPlugin} = require('vue-loader')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const ProgressBarPlugin = require('progress-bar-webpack-plugin')
const path = require('path')
const Dotenv = require('dotenv-webpack')
function getConfigPath(mode) {
return path.resolve(process.cwd(), `.env.${mode}`)}module.exports = {
entry: './src/main.ts'.cache: {
type: 'filesystem' // Persistent cache
},
output: {
filename: 'js/[name].[chunkhash:5].js'.path: path.resolve(__dirname, ".. /dist")},module: {
rules: [{test: /\.(t|j)s$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',},],}, {test: /\.(t|j)s$/,
exclude: /node_modules/,
use: [
{
loader: 'ts-loader'.options: {
// Specify a specific TS compilation configuration to distinguish the script's TS configuration
configFile: path.resolve(__dirname, '.. /tsconfig.json'),
// Add a. Ts or. TSX suffix to the corresponding file
appendTsSuffixTo: [/\.vue$/].transpileOnly: true // Turn off type detection, that is, value translation},},],}, {test: /\.css$/,
use: [
// 'vue-style-loader',
// 'style-loader',
MiniCssExtractPlugin.loader,
'postcss-loader'.'css-loader'],}, {test: /\.less$/,
use: [
// 'vue-style-loader',
MiniCssExtractPlugin.loader,
// 'style-loader',
'css-loader'.'postcss-loader'.'less-loader'],}, {test: /\.(gif|jpg|png|woff|svg|eot|ttf)\?? . * $/,
use: [
{
loader: 'url-loader'.options: {
limit: 1024,},}]}]},optimization: {
splitChunks: {
chunks: 'async'.minSize: 20000.minChunks: 1.// The minimum number of uses
maxAsyncRequests: 5.maxInitialRequests: 3.minChunks: 1.cacheGroups: {
// Extract the public js
commons: {
chunks: "all".// initial
minChunks: 2.maxInitialRequests: 5.minSize: 0.name: "commons"}}}},resolve: {
extensions: [".ts".".tsx".".js".".json"],},plugins: [
new HtmlWebpackPlugin({
template: './public/index.html'.filename: 'index.html'.title: 'webpack5+Vue3'
}),
new VueLoaderPlugin(),
new MiniCssExtractPlugin({
filename: "style/[name].[hash:8].css".chunkFilename: "style/[hash:8].css"
}),
new ForkTsCheckerWebpackPlugin(),
]
}
Copy the code
webpack.dev.config.js
const { merge } = require('webpack-merge')
const common = require('./webpack.base.config')
// const SpeedMeasurePlugin = require("speed-measure-webpack-plugin")
// const smp = new SpeedMeasurePlugin()
module.exports = merge(common,{
mode: 'development'.devtool: 'source-map'.devServer: {
port: 9091.// Local server port number
// hot: true, // hot overload
// overlay: true // If the code fails, a "floating layer" pops up on the browser page. Similar to vuE-CLI scaffolding
disableHostCheck: true}})Copy the code
webpack.prod.config.js
const { merge } = require('webpack-merge')
const common = require('./webpack.base.config')
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
module.exports = merge(common,{
mode: 'production'.plugins: [
new CleanWebpackPlugin()
]
})
Copy the code
The configuration script
package.json
."scripts": {
"server": "cross-env NODE_ENV=development webpack serve --progress --hot --inline --config build/webpack.dev.config.js"."build": "cross-env NODE_ENV=production webpack --mode=production --config build/webpack.prod.config.js"},...Copy the code
4. Configuration tsconfig. Json
{
"compilerOptions": {
"target": "esnext"."module": "esnext"."strict": true."jsx": "preserve"."importHelpers": true."moduleResolution": "node"."experimentalDecorators": true."skipLibCheck": true."esModuleInterop": true."allowSyntheticDefaultImports": true."sourceMap": true."baseUrl": "."."types": [
"webpack-env"."node"]."paths": {
"@ / *": [
"src/*"]},"lib": [
"esnext"."dom"."dom.iterable"."scripthost"]},"include": [
"src/**/*.ts"."src/**/*.tsx"."src/**/*.vue"]."exclude": [
"node_modules"]}Copy the code
The project configured here is ready to run, but a few questions remain: Ts can compile to the specified version of JS, so does Babel still need to be used?
TSC’s target only translates syntax and does not integrate polyfill, so Babel is still required.
For example, convert arrow functions to normal functions and aysnc + await to promise. then, this is syntactic translation.
If there is no Promise. But you run surroundings prototype. Finally, then no or not.
So we still need Babel in the project.
Existing solutions for Webpack translation of Typescript:
plan | 1 | 2 | 3 |
---|---|---|---|
Single-process scenario (type checking and translation in the same process) | Ts – loader (transplieOnly to false) | awesome-typescript-loader | |
Multiprocess scheme | Ts – loader (transplieOnly to true + fork – ts – the checker – webpack – the plugin) | Awesome-typescript-loader + comes with Checkplugin | babel+fork-ts-checker-webpack-plugin |
Considering performance and scalability, Babel + fork-ts-Checker -webpack-plugin is currently recommended.
Before babel7, it was necessary to use both ts-loader and babel-loader. The compilation process of ts > TS compiler > JS > Babel > JS. Compiling JS twice is inefficient. But babel7 comes out with the ability to parse typescript, and with this level of support, we can just use Babel without having to go through another TS compilation process.
In Babel 7, we use the new @babel/preset-typescript preset, which, combined with a few plug-ins, can parse most of the TS syntax.
So how does Babel handle TypeScript code?
Babel removes all TypeScript, converts it to regular JavaScript, and continues to process it in its own way. Removing typescript eliminates the need for type checking and annoying type errors, which makes compiling faster.
Add Babel to parse typescript
Install the following dependencies --save-dev # webpack loader babel-loader # Babel core @babel/core # Intelligent conversion to the target runtime environment code @babel/preset-env # recall Support for TS class writing @babel/preset-typescript # polyfill @babel/plugin- transform-Runtime @babel/plugin-proposal-class-propertiesInstall the following dependencies --save
@babel/runtime
@babel/runtime-corejs3
"core-js":" ^ 3.11.0"Copy the code
Delete ts-loader and add babel-loader
{
test: /\.(t|j)s$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',},],}Copy the code
Add the Babel configuration file babel.config.js to the project root directory
module.exports = {
presets: [['@babel/preset-env',
{
useBuiltIns: 'usage'.// Introduce polyfill on demand
corejs: 3,}], ['@babel/preset-typescript'.// Reference the Typescript plug-in
{
allExtensions: true.All file extensions are supported, otherwise using ts in vue files will cause an error},]].plugins: [['@babel/plugin-transform-runtime',
{
corejs: 3],},'@babel/proposal-class-properties'
// '@babel/proposal-object-rest-spread',],}Copy the code
Consider: Vue-CLI automatically creates scaffolding projects that can read configurations according to.env.production,.env.development, how should this be implemented?
Dotenv-webpack can be used with the cross-env NODE_ENV=development environment specified before executing the script.
Other plugins: Speed-measure-webpack-plugin Package speed analysis Webpack-bundle-Analyzer Package result analysis… Of course, there are many other plug-ins.
Finally, attach the code: address