preface
Recently, I reviewed the knowledge of Webpack, and felt that it is not good to learn Webpack just by watching it without practicing it, so I came up with the idea of manually building a Vue3+Ts running environment. Without further ado, just start building.
Create a folder and go to the directory
Generate package.json file
If your directory name is valid, just add -y. This means yes for all options.
npm init
Copy the code
Install Webpack, webPack – CLI
Here webpack and Webpack-CLI are required in the development environment, but not in the build environment. So plus minus D theta
npm install webpack webpack-cli -D
Copy the code
Create the script in package.json
We can package directly from the command line via NPX webpack, but we can also create a build script in the package.json file to perform the package via NPM run build.
Create the WebPack configuration file
By default, webpack can be configured by creating a webpack.config.js file in the root directory. However, there may be more commands to be configured later. So here we split the webPack configuration file. Create a webpack_config folder in the root directory. Within this folder, create three files: Webpack.common.js (for general configuration), webpack.dev.js (for development environment configuration), webpack.prod.js (for production environment configuration).
Because by default, webpack reads the configuration of the webpack.config.js file, we are not modifying the file for configuration, so we need to specify the directory of the configuration file. We can set it directly in the script command in package.json file.
Configure the webpack.common.js file as follows
const path = require('path')
module.exports = {
entry: './src/main.js'.// Set the packaged entry file, there is no need to.. /. Because this is relative to context, and the path to context is the root directory.
output: {
path: path.resolve(__dirname, '.. /bundle'), // There is a need for... /, because this is not relative to context.
publicPath: '/'To configure the prefix to import resources into index.html after packagingfilename: 'js/[name].[chunkhash:6].bundle.js'.clean: true // Delete the packed files before packing them.}}Copy the code
Handle CSS, less files
Install csS-loader to process CSS files. Install style-loader (to insert styles into HTML using style tags).
Install less-loader to process less files.
Install postCSs-loader, postCSs-preset -env (this is a plugin) for adding browser prefixes to CSS files.
npm install css-loader style-loader less-loader postcss-loader postcss-preset-env -D
Copy the code
configure
/ / on the webpack.com mon. Js
module.exports = {
...
module: {
rules: [{test: /\.css$/.// Matches the CSS file
use: [
"style-loader",
{
loader: "css-loader".options: {
importLoaders: 1.// there are several loaders before csS-loader}, {},loader: "postcss-loader".options: {
postcssOptions: { // The configuration of postCSS can also be extracted into a separate file, which is not extracted here.
plugins: ['postcss-preset-env'],}},},],}, {test: /\.less$/,
use: [
'style-loader',
{
loader: 'css-loader'.options: {
importLoaders: 2}}, {loader: 'postcss-loader'.options: {
postcssOptions: {
plugins: ['postcss-preset-env']}}},'less-loader']]}},Copy the code
Handle images and font resources
In Webpack5, you can use asset Module Type to handle these resources without installing file-loader or url-loader.
configure
// webpack.common.js
module.exports = {
...
module: {
rules: [{test: /\.(jpe? g|svg|png)$/.// Matching resources
type: 'asset'.// asset is a combination of file-loader and url-loader
generator: {
filename: 'img/[name].[hash:6][ext]' // The generated file name
},
parser: {
dataUrlCondition: {
maxSize: 10 * 1024 // If the generated image is less than 10KB, no image will be generated and base64 will be converted}}}, {test: /\.(tff|woff|ttf)$/,
type: "asset".generator: {
filename: "fonts/[name].[hash:6][ext]",},parser: {
dataUrlCondition: {
maxSize: 8 * 1024,},},},]}}Copy the code
Generating HTML files
So far, our packaged files have no HTML files. If we want to generate HTML files after packaging, we can use the HTml-webpack-plugin to help us generate HTML files. The generated HTML will automatically help us with the file import.
HTML – webpack – the plugin installation.
npm install html-webpack-plugin -D
Copy the code
When using the plugin, we can either specify an HTML template for it or have it automatically generate HTML files for us
configure
// webpack.common.js
const HtmlWebpackPlugin = require('html-webpack-plugin') // Import the plug-in
module.exports = {
...
plugins: [
new HtmlWebpackPlugin() // If you need to further configure the plug-in, you can do your own research]}Copy the code
Creating a service
During vUE development, we execute NPM Run Serve to create a local service. In Webpack, if you want to create a local service, you need to install webpack-dev-server
npm install webpack-dev-server -D
Copy the code
Create a script in package.json file
Then run NPM run serve to start a local service.
With the local service created, we can do some configuration for the local service. These configurations are used during development and not during packaging, so the previous configurations are separated here.
Separate configuration files
First, when executing the script, we can pass in a parameter so that we can determine whether we currently want to use a development configuration or a production configuration.
When our configuration file exports a function, WebPack passes us the parameters we pass as parameters to the function, and we can use this parameter to decide which configuration to use.
In addition to getting the configuration mode, we also need to merge the configuration commands. You can use the Webpack-Merge plug-in to help you merge configurations.
npm install webpack-merge -D
Copy the code
// webpack.common.js
const { merge } = require('webpack-merge') // Merge function
const commonConfig = {} // This object holds the previous configuration
module.exports = (env) = > {
// Determine the current mode
const mode = env.production ? 'production' : 'development'
let config = null
// Import different configurations according to different modes
if (mode === 'production') {
config = require('./webpack.prod')}else {
config = require('./webpack.dev')}// Returns the merged configuration file
return merge(commonConfig, config)
}
Copy the code
Configuration devServer
// webpack.dev.js
module.exports = {
mode: 'development'.devtool: 'cheap-module-source-map'.// Set source-map file for easy debugging of development code
devServer: {
hot: true.// Enable module hot replacement, which is enabled by default
historyApiFallback: { // The route history mode refresh page is lost
rewrites: [{from: / \. * /.// Match all paths
to: '/index.html' // Map to the index.html file}]}}}Copy the code
Working with JS files
When packaging, in order to do browser adaptation, we need to install ES6+ JS into ES5 code. At this point we can use Babel to help us change.
Install babel-loader @babel/ core@babel /preset-env.
npm install @babel/core @babel/preset-env @babel-loader -D
Copy the code
configure
Because of the adaptation of JS code, it only needs to be converted at packaging time. There is no need to transform the code during development, so just configure it in the PROd file.
module.exports = {
mode: 'production'.module: {
rules: [{test: /\.js$/,
exclude: /node_modules/.// Do not process js files under node_modules, so it does not consume packaging time
use: {
loader: 'babel-loader'.options: {
presets: ['@babel/preset-env'}}}]}}Copy the code
Processing TS files
Ts files can be processed using babel-loader and @babel/preset-typescript, as well as TS-loader. Here I use the development of the use of TS-loader so that the following TS error detection. Package using babel-loader, so you can convert js to do compatibility processing.
To use ts-loader, you must have the tsconfig.json file. If not, you can use TSC –init on the terminal. If an error is reported, install typescript globally.
npm install @babel/preset-typescript ts-loader typescript -D
Copy the code
configure
Configuration in the development environment
// webpack.dev.js
module.exports = {
...
module: {
rules: [{test: /\.ts$/,
exclude: /\.ts$/,
use: {
loader: 'ts-loader'.options: {
appendTsSuffixTo: [/\.vue$/].// Handle using ts in vue files
transpileOnly: true.// Turn off type detection to reduce compile time.}}}]}}Copy the code
In the above configuration, we turned off type checking to reduce compilation time, and we could have handed over the responsibility of type checking to another plug-in that would have started another thread to help us with type checking.
Install the fork-ts-checker-webpack-plugin
npm install fork-ts-checker-webpack-plugin -D
Copy the code
Add the use of this plug-in to the configuration above.
// webpack.dev.js
const ForkTsCheckerWebapckPlugin = require('fork-ts-checker-webpack-plugin')// Import the plug-in
module.exports = {
...
module: {
rules: [{test: /\.ts$/,
exclude: /node_modules/,
use: {
loader: 'ts-loader'.options: {
appendTsSuffixTo: [/\.vue$/].// Handle using ts in vue files
transpileOnly: true.// Turn off type detection to reduce compile time.}}}]}plugins: [
new ForkTsCheckerWebpackPlugin()
]
}
Copy the code
Configuration in the generation environment
// webpack.prod.js
module.exports = {
...
module: {
rules: [{test: /\.ts$/,
use: {
loader: 'babel-loader'.options: {
presets: [
'@babel/preset-env'['@babel/preset-typescript', {
// This configuration is used to process ts files after.vue files have been parsed
allExtensions: true}}}}}Copy the code
Processing. Vue files
To process.vue files, vue-Loader and @vue/ Compiler-sFC are required. Because you are currently working with vue3 files, and vue3 is not the default version, you need to install vue-loader@next. When vue3 becomes the default version, you can install it directly.
npm install @vue/compiler-sfc vue-loader@next -D**
Copy the code
This is because.vue files need to be processed in both development and build environments. So here we put the processing configuration for the.vue file in the webpack.common.js file.
configure
const { VueLoaderPlugin } = require('vue-loader') / / import VueLoaderPlugin
module.exports = {
...
module: {
rules: [{test: /\.vue$/,
exclude: /node_modules/,
loader: 'vue-loader'}},plugins: [
new VueLoaderPlugin() // Use this plugin here]}Copy the code
Once packaged, runtime will find the following warning
This warning means that Vue strongly recommends that we define our own variables __VUE_OPTION_API_ and VUE_PROD_DEVTOOLS, which are used to decide whether to use optionsAPI and whether to enable the Devtools plugin. We can define it according to our own situation.
How to define global variables in Webpack can be done using the DefinePlugin built into WebPack.
// webpack.common.js
const { DefinePlugin } = require('webpack')
module.exports = { ... Plugins:new DefinePlugin({
__VUE__OPTION_API__: false.__VUE_PROD__DEVTOOLS: true}})]Copy the code
Once you have defined the global variable, open it again and you will find no warning.
conclusion
With the basic configuration above, we are ready to run vue3 and TS projects. There are also some optimizations that need to be made to the project, which will be addressed later.