Use webpack to build a vue development environment (2)

Use webpack to build a vue development environment (2)

After the last time, the second article began to further configure

The old rules, continue to develop based on the v0.0.1 code, this time the code after the configuration will be divided into v0.0.2

Use less to improve the development experience

Install and use css preprocessor -less

npm install --save-dev less less-loader

Modify the configuration, because testthat can receive regular expression, then for cssand lessmatch, we can write:test: /\.(less|css)$/,

  • webpack.base.js

Modify the original test:/\.css$/module

module.exports = {
    
    
  // ...
  module: {
    
    
    rules: [
      {
    
    
        test: /\.(less|css)$/,
        use: ['vue-style-loader', {
    
     loader: 'css-loader', options: {
    
     esModule: false } }, 'less-loader']
      }
    ]
  }
  // ...
}

After the configuration is complete, go back App.vue. We add it on the style tag lang="less". And write it according to the less grammar

  • View app
<style lang="less">
  .text-red {
     
     
    color: #000;
  }

  .avatar {
     
     
    width: 100px;
    height: 100px;
    &.bg-avatar {
     
     
      background-image: url('./assets/image/avatar.jpg');
      background-size: 100% 100%;
      background-repeat: no-repeat;
    }
  }
</style>

Can create a new /src/assets/css/common.lessfile, try @importto introduce the function

  • /src/assets/css/common.less
body {
  background-color: #909090;
}
  • View app
<style lang="less">
  @import './assets/css/common.less';
  .text-red {
     
     
    color: #000;
  }

  .avatar {
     
     
    width: 100px;
    height: 100px;
    &.bg-avatar {
     
     
      background-image: url('./assets/image/avatar.jpg');
      background-size: 100% 100%;
      background-repeat: no-repeat;
    }
  }
</style>

You can see that they are all in effect, because of the previous ones url-loader. So when we introduced the files, it was smooth and profitable~

Configure CSS prefix auto-completion

The major browsers have different prefixes. It is too painful to type them one by one. Can you imagine that border-raidus will also have compatible prefixes (although it is supported by all browsers now)

To automatically add a prefix to the package, it is necessary to use postcss-loader, andautoprefixer

npm i autoprefixer postcss-loader -D

Before configuration, let me talk about a few pits. If the configuration of postcss-loader and autoprefixer is invalid, you can pay attention to:

  • Before configuring Autoprefixer, you need to add it first Browserslist. Can be a plus in the root directory .browserslistrc, the file can also package.jsonadd file: browserslist. But it must be added, otherwise the autoprefixer will not take effect

  • Second, you must create a directory in the root postcss.config.jsbehind will talk

  • Autoprefixer version processing

  • webpack.base.js

According to Loader 从右往左的执行顺序, we postcss-loaderarrange in the penultimate position.

module.exports = {
    
    
  // ...
  module: {
    
    
    rules: [
      {
    
    
        test: /\.(less|css)$/,
        use: [
          'vue-style-loader',
          {
    
     loader: 'css-loader', options: {
    
     esModule: false } },
          'postcss-loader',
          'less-loader'
        ]
      }
    ]
  }
  // ...
}
  • package.json
    I do not pay more files, this configuration is done directly in package.json
{
    
    
  "browserslist": ["last 2 version", "> 1%", "iOS >= 7", "Android > 4.1", "Firefox > 20"]
}
  • Add the file postcss.config.js to the root directory
module.exports = {
    
    
  plugins: [require('autoprefixer')]
}

Why do I need to create it separately postcss.config.js, can't I write it in the webpack configuration?

After testing, postcss.config.jsthe purpose of existence is because webpack is postcss-loaderno longer supported write pluginsa. Therefore, additional files are required for configuration.

configuration has an unknown property 'rules'. These properties are valid:
   object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, externals?, infrastrdule?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, resolve?, resolveLoader?, serve?, stats?, target?, watch?, watchOptions? }

The easiest way to add a css test that needs to be prefixed is display:flex;. See the effect

Why, because the automatic installation autoprefixerversion is too high, I installed the "autoprefixer": "^10.0.0"
concrete can look at the issues

Next to autoprefixerdowngrade a

npm uninstall autoprefixer

npm install [email protected] -D

In the end, the prefix is ​​automatically incomplete.

Configure css style separation

Key point: Before starting to use the separation of css style and JS, you must be very clear about the difference between / and ./ in publicPath! !
If you don’t understand the role of publicPath, you can read this part first: The difference between publicPath in webpack/vue-cli

After working for so long, the prefix of css is finally OK, but I
didn’t find the effect of packaging. The original css is mixed in JS, which also means that the original large JS file is now even worse. , In case the page style is complicated enough, I can’t believe it

Then use the mini-css-extract-pluginconfiguration css separation and compression

npm i mini-css-extract-plugin -D
  • webpack.base.js

Css or change the module, this time to vue-style-loaderget rid of
and the situation css output folder to configure a non-root directory, you need to configure publicPath. According to the difference of publicPath in webpack/vue-cli mentioned before, I use it in the development environment /. Used in a production environment ../. MiniCssExtractPlugin.loaderAlso configure publicPath separately ../. Don't know why, remember to read the previous link~

const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
    
    
  output: {
    
    
    filename: '[name].[contenthash].js',
    publicPath: './', // base.js 中的这个配置其实会被后面覆盖掉,所以写哪个都没关系
    path: path.resolve(ROOT_PATH, 'dist')
  },
  module: {
    
    
    rules: [
      // ...
      {
    
    
        test: /\.(less|css)$/,
        use: [
          {
    
    
            loader: MiniCssExtractPlugin.loader,
            options: {
    
    
              publicPath: '../' // 注意添加了输出路径
            }
          },
          {
    
     loader: 'css-loader', options: {
    
     esModule: false } },
          'postcss-loader',
          'less-loader'
        ]
      }
    ]
  },
  plugins: [
    // ...
    new MiniCssExtractPlugin({
    
    
      // css的分离到了单独的 css 目录下,并且哈希值继续使用 contenthash
      filename: 'css/[name].[contenthash:4].css'
    })
  ]
}
  • webpack.dev.js
const baseConfig = require('./webpack.base')
const {
    
     merge } = require('webpack-merge')
const path = require('path')
const ROOT_PATH = path.resolve(__dirname, '../')

module.exports = merge(baseConfig, {
    
    
  mode: 'development',
  output: {
    
    
    filename: '[name].[contenthash].js',
    publicPath: '/', // dev 环境下记得使用 / 不然会有其他问题
    path: path.resolve(ROOT_PATH, 'dist')
  }
})
  • webpack.prod.js
const baseConfig = require('./webpack.base')
const {
    
     merge } = require('webpack-merge')
const {
    
     CleanWebpackPlugin } = require('clean-webpack-plugin')
const path = require('path')
const ROOT_PATH = path.resolve(__dirname, '../')

module.exports = merge(baseConfig, {
    
    
  mode: 'production',
  output: {
    
    
    filename: '[name].[contenthash].js',
    publicPath: './', // prod 的配置和dev目前是差不多的,不过 publicPath 换成了 './'
    path: path.resolve(ROOT_PATH, 'dist')
  },
  // 而且还多了一个打包清空dist的插件
  plugins: [new CleanWebpackPlugin()]
})

Run it to see the effect, the image prefix in css has been completed ../, it seems to have taken effect

Finally, I still emphasize the understanding of publicPath configuration. The advantage of writing webpack by yourself is that you know the process of each work!

Use babelto convert ES6 to ES5

Now the Vue environment is also available, and less is installed (saas is the same, I can add a plug-in configuration when I have time), and then CSS auto-completion is no problem, and the file separation pit is also stepped on.

But miss the most important question -let's open the IE browser:

This problem is not surprising, JS syntax has to be lower compatible, babel is no stranger to this

Installation babel-loader, but it is also dependent on the plug-in the other plug-ins: @babel/core, @babel/plugin-transform-runtime,@babel/preset-env

npm i babel-loader @babel/core @babel/plugin-transform-runtime @babel/preset-env -D
  • webpack.base.js

Add a conversion to exclude the node_modules package

module.exports = {
    
    
  module: {
    
    
    rules: [
      // ...
      {
    
    
        test: /\.m?js$/,
        exclude: /node_modules/,
        use: {
    
    
          loader: 'babel-loader',
          options: {
    
    
            presets: ['@babel/preset-env'],
            plugins: ['@babel/plugin-transform-runtime']
          }
        }
      }
    ]
  }
  // ...
}

Then re-run the project, go to IE to see the situation: No problem

Pack it, then run it with http-serve (mainly want to verify if there will be bugs in the package), remember to use http-serve. Otherwise I won’t be able to preview

The grammar conversion of js is also OK. It seems that writing configuration is getting more and more smooth!

Organize project resources

Prior to v0.0.2 ending, we look again write the configuration: webpack-base.js, webpack-dev.js, webpack-prod.js. What are the public places:

2 public directories

  • ROOT_PATH
  • path.resolve(ROOT_PATH, ‘dist’)

This piece is also a migration first, and write a public configuration file, so that no matter where the configuration file goes, the directory will basically not be messed up.

In builda new folder PATH.js, used to store directory project we want to use

Organized several folders, the packaged dist file directory, and the index.html file of the template file, entry files, etc. This part of the organization is also paving the way for the subsequent multi-entry pages

  • build/PATH.js
const path = require('path')
const ROOT = path.resolve(__dirname, '../')
const DIST = path.resolve(ROOT, 'dist')

const tmp_main = path.resolve(ROOT, 'src/main.js')
const TEMPLATE_HTML = path.resolve(ROOT, 'public/index.html')

module.exports = {
    
    
  ROOT,
  DIST,
  TEMPLATE_HTML,
  tmp_main
}
  • webpack.base.js
// 注意2个地方被注释掉了,统一从PATH引入
// const path = require('path')
// const ROOT_PATH = path.resolve(__dirname, '../')
const {
    
     DIST, tmp_main, TEMPLATE_HTML } = require('./PATH')

module.exports = {
    
    
  output: {
    
    
    filename: '[name].[contenthash].js',
    publicPath: './',
    path: DIST // 改动了这里的PATH
  },
  // ...
  plugins: [
    // ...
    // 设置html模板生成路径
    new HtmlWebpackPlugins({
    
    
      filename: 'index.html',
      template: TEMPLATE_HTML, // 改了 template 的目录
      chunks: ['main'] // 指定在html自动引入的js打包文件
    })
  ]
}
  • The
    changes to the two files of webpack-dev.js and webpack-prod.js are also the same, so I won’t repeat them.
// 注意2个地方被注释掉了,统一从PATH引入
// const path = require('path')
// const ROOT_PATH = path.resolve(__dirname, '../')
const {
    
     DIST } = require('./PATH')

// output.path 改一下为 DIST 就可以了

At last

The webpack stepping on the pit series (2) is also over~. Introduced the use of less, css style separation, css prefix completion, in order to be compatible with the JS conversion done by IE Big Brother

The changed files are as follows:



But now the project still packs a page, and my idea is to make one 多入口的单页面应用. It may not do nuxtso much less complicated, but in a sense you can reduce the problem of loading the first screen -

The next preview:

  • What kind of hot update is the hot update of the current project?
  • Realize a simple multi-entry
  • Realize automatic access to the entrance (the highlight)
  • Add the URL output after the code is run

My original blog address, click to improve SEO inclusion, thank you~ Use webpack to build a vue development environment (2)

Guess you like

Origin blog.csdn.net/Jioho_chen/article/details/108826627