After 8102 years, it’s a bit late to talk about webPack configuration. Also, projects generated based on vue-CLI or create-react-app already have WebPack configured for us in one click, which doesn’t seem to require any further knowledge.
However, in order to learn and understand what front-end pain points WebPack solves, it is necessary to build a simple development environment from scratch. The webpack configuration in this article refers to the Webpack-Simple template that vuE-CLI provides. This is also the simplest webpack configuration in VUe-CLI, which is perfect for learning from scratch.
Note: This webpack is based on 3.10.0
Demo code download
Install webpack
npm i webpack -g
Copy the code
Project initialization
Create a new folder vue-webpack-simple
The new package. The json
npm init -y
Copy the code
Install vue webpack webpack-dev-server
npm i vue --save
Copy the code
npm i webpack webpack-dev-server --save-dev
Copy the code
Create index.html in the root directory
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
</body>
</html>
Copy the code
Create webpack.config.js in the root directory
var path = require('path');
var webpack = require('webpack');
module.exports = {};
Copy the code
Create a SRC folder and create main.js under the SRC folder
The current structure of the project is as follows:
Js modular
Before ES6, JS was not a unified module system. The server side uses the CommonJS specification, while the browser side has both AMD and CMD specifications
The idea behind WebPack is that everything is a module, and the commonJS specification is officially recommended, which allows us to use commonJS modular writing on the browser side
module.exports = {}
Copy the code
Create a new util.js file under SRC
module.exports = function say() {
console.log('hello world');
}
Copy the code
main.js
var say = require('./util');
say();
Copy the code
Modify the webpack. Config. Js
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: './src/main.js'.// The project entry file, webpack will start from main.js and load and pack all dependent JS files
output: {
path: path.resolve(__dirname, './dist'), // The package file path of the project
publicPath: '/dist/'.// Access path through devServer
filename: 'build.js' // The packaged file name
},
devServer: {
historyApiFallback: true.overlay: true}};Copy the code
Modify the package. Josn
"scripts": {
"dev": "webpack-dev-server --open --hot"."build": "webpack --progress --hide-modules"
},
Copy the code
Note: Webpack-dev-server automatically starts a static resource Web server — the hot parameter starts hot updates
Modify index.html to introduce packaged files
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script src="/dist/build.js"></script>
</body>
</html>
Copy the code
run
npm run dev
Copy the code
You can find a page that opens automatically in your browser, check the console, and it has Hello World typed
We can modify util.js at will and notice that the browser automatically refreshes, which is very convenient.
If we want to see the bundled bundle.js file, run it
npm run build
Copy the code
You can see that a dist directory is generated, which contains the bundled bundle.js
Transcoding es6 is not supported by Webpack by default, but the import export syntax is supported separately. So we can rewrite the previous modular notation
util.js
export default function say() {
console.log('hello world ');
}
Copy the code
main.js
import say from './util';
say();
Copy the code
The introduction of vue
Let’s try to introduce vUE (single file.vue is not considered for now)
main.js
import Vue from 'vue';
var app = new Vue({
el: '#app'.data: {
message: 'Hello Vue! '}});Copy the code
index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
{{message}}
</div>
<script src="/dist/build.js"></script>
</body>
</html>
Copy the code
One more note: the webpack.config.js file needs to be modified
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: './src/main.js'.output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/'.filename: 'build.js'
},
devServer: {
historyApiFallback: true.overlay: true
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'}}};Copy the code
Re-run NPM run dev, and you can see that Hello World is displayed normally
Introduce SCSS and CSS
Webpack only supports js modularity by default. If you need to import other files as modules, you need the corresponding Loader parser
npm i node-sass css-loader vue-style-loader sass-loader --save-dev
Copy the code
webpack.config.js
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: './src/main.js'.output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/'.filename: 'build.js'
},
devServer: {
historyApiFallback: true.overlay: true
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'}},module: {
rules: [{test: /\.css$/.use: [
'vue-style-loader'.'css-loader'],}]}};Copy the code
Explanation:
{
test: /\.css$/.use: [
'vue-style-loader'.'css-loader'],}Copy the code
Loader (CSS); loader (vue); loader (CSS); loader (vue); loader (CSS);
Note: since we are developing with VUE here, we use vue-style-loader, otherwise we use style-loader
Cs-loader allows you to import CSS in a modular way. Vue-style-loader inserts the imported CSS into the style tag of the HTML page
The same configuration is used to introduce SCSS:
module: {
rules: [{test: /\.css$/.use: [
'vue-style-loader'.'css-loader'],}, {test: /\.scss$/.use: [
'vue-style-loader'.'css-loader'.'sass-loader'],}, {test: /\.sass$/.use: [
'vue-style-loader'.'css-loader'.'sass-loader? indentedSyntax']],}}Copy the code
Let’s try to create a new style directory in SRC and create common.scss in style
body {
background: #fed;
}
Copy the code
main.js
import './style/common.scss';
Copy the code
Found CSS styles useful
Use Babel transcoding
The ES6 syntax is still not supported by most browsers, so Bable can transcode ES6 to ES5 syntax so that we can be bold and use the latest features in our projects
npm i babel-core babel-loader babel-preset-env babel-preset-stage-3 --save-dev
Copy the code
Create a new. Babelrc file in the project root directory
{
"presets": [["env", { "modules": false}]."stage-3"]}Copy the code
Webpack.config. js adds a loader
{
test: /\.js$/.loader: 'babel-loader'.exclude: /node_modules/
}
Copy the code
Exclude excludes the files in the node_modules folder without transcoding
Now let’s try the async await syntax util.js
export default function getData() {
return new Promise((resolve, reject) = > {
resolve('ok'); })}Copy the code
main.js
import getData from './util';
import Vue from 'vue';
import './style/common.scss';
var app = new Vue({
el: '#app'.data: {
message: 'Hello Vue! '
},
methods: {
async fetchData() {
const data = await getData();
this.message = data;
}
},
created() {
this.fetchData(); }});Copy the code
And then the console will say regeneratorRuntime is not defined because we didn’t install babel-Polyfill
npm i babel-polyfill --save-dev
Copy the code
Then modify the entry to webpack.config.js
entry: ['babel-polyfill'.'./src/main.js'].Copy the code
Rerun NPM run dev and you can see that it is running properly
Importing image resources
Introduce images as modules as well
npm i file-loader --save-dev
Copy the code
Webpack.config. js adds a loader
{
test: /\.(png|jpg|gif|svg)$/.loader: 'file-loader'.options: {
name: '[name].[ext]? [hash]'}}Copy the code
Create an img directory under the SRC directory and save the image logo.png
Modify the main js
import getData from './util';
import Vue from 'vue';
import './style/common.scss';
Vue.component('my-component', {
template: '<img :src="url" />',
data() {
return {
url: require('./img/logo.png')}}})var app = new Vue({
el: '#app'.data: {
message: 'Hello Vue ! '
},
methods: {
async fetchData() {
const data = await getData();
this.message = data;
}
},
created() {
this.fetchData()
}
});
Copy the code
Modified index. HTML
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
{{message}}
<my-component/>
</div>
<script src="/dist/build.js"></script>
</body>
</html>
Copy the code
As you can see, the image also loads correctly
Single file component
In the previous example, we used Vue.com Ponent to define global components. In real projects, single-file components are preferred
npm i vue-loader vue-template-compiler --save-dev
Copy the code
Add a Loader
{
test: /\.vue$/.loader: 'vue-loader'.options: {
loaders: {
'scss': [
'vue-style-loader'.'css-loader'.'sass-loader'].'sass': [
'vue-style-loader'.'css-loader'.'sass-loader? indentedSyntax']}}}Copy the code
Create a new app.vue in the SRC directory
<template>
<div id="app">
<h1>{{ msg }}</h1>
<img src="./img/logo.png">
<input type="text" v-model="msg">
</div>
</template>
<script>
import getData from './util';
export default {
name: 'app',
data () {
return {
msg: 'Welcome to Your Vue.js'
}
},
created() {
this.fetchData();
},
methods: {
async fetchData() {
const data = await getData();
this.msg = data; }}}</script>
<style lang="scss">#app { font-family: "Avenir", Helvetica, Arial, sans-serif; h1 { color: green; }}</style>
Copy the code
main.js
import Vue from 'vue';
import App from './App.vue';
import './style/common.scss';
new Vue({
el: '#app'.template: '<App/>'.components: { App }
})
Copy the code
index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script src="/dist/build.js"></script>
</body>
</html>
Copy the code
NPM run dev, you can see that the single file is loaded correctly
source-map
Debugging is also an important requirement during the development phase.
App.vue
created() {
this.fetchData();
console.log('23333');
}
Copy the code
So let’s intentionally hit a console, open the console
Let’s click to get to the details of the console
What I got was a packaged build.js, and I didn’t know which component it was written in, which made debugging difficult
At this point, modify webpack.config.js
module.exports = {
entry: ['babel-polyfill'.'./src/main.js'].// omit other...
devtool: '#eval-source-map'
};
Copy the code
NPM run dev
Packaging releases
Let’s try the NPM run build package first
As you can see, the build.js package is very large, over 500 k
In the actual release, the file will be compressed, cached, separated and other optimization
npm i cross-env --save-dev
Copy the code
Modify the package. The json
"scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot"."build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
}
Copy the code
This time we set the environment variable, and when we package, NODE_ENV is production
Then modify webpack.config.js and compress the JS code if NODE_ENV is production
var path = require('path');
var webpack = require('webpack');
module.exports = {
/ / to omit...
}
if (process.env.NODE_ENV === 'production') {
module.exports.devtool = '#source-map';
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'}}),new webpack.optimize.UglifyJsPlugin(),
])
}
Copy the code
repack
As you can see, the compression is very strong!
At this point, a very simple VUE development environment has been set up.
Note: The configuration in this article can be optimized in many ways, such as separating JS and CSS
It’s up to the reader to find out, but this is just a basic webPack configuration guide.