从零搭建前端开发环境(零)——基础篇:2.webpack生产与开发环境配置

接下来就要进行工程化的操作了,主要有两个目的。

  1. 对静态文件进行编译、打包、压缩、版本控制等优化操作;
  2. 构建一个便利的开发环境,比如热加载、代理等。

这里我们会用到webpack,辅以babel以及其他loader来处理js、css、图片等静态文件。对于各种loader的作用,本文会有一个大概的介绍,但不会展开说明,推荐看webpack文档来做一个详细的了解。

1、安装webpack及各种loader和plugin

$ npm i -D webpack@3 webpack-dev-server@2 webpack-merge babel-core babel-loader babel-preset-env babel-preset-stage-2 css-loader style-loader less less-loader postcss-loader postcss-import postcss-url url-loader file-loader extract-text-webpack-plugin html-webpack-plugin

(注:截止至笔者写作日,webpack4还不稳定,所以还是用webpack3,相应的需要webpack-dev-server@2)

说明:

  • babel-core、babel-loader、babel-preset-env、babel-preset-stage-2,babel相关负责将js编译为es5规范,要新增.babelrc配置文件。
  • css-loader、style-loader,负责css的编译,webpack文档里可以找到。
  • postcss-loader、postcss-import、postcss-url,postcss负责给样式添加浏览器前缀的兼容(如-webkit-),要新增.postcssrc.js配置文件。
  • less、less-loader样式预编译,当然也可以用sass。
  • url-loader,负责img、font等静态文件编译。
  • extract-text-webpack-plugin,负责将css提取为单独的文件。
  • html-webpack-plugin,负责向html模板中动态写入静态文件引用。

2、修改代码

src/index.css重命名为src/index.less

src/index.js(所有资源都用import引入,并把方法提取到util.js文件,方便后面的内容)

import { strReverse } from '@util';
import './index.less';
import logo from './assets/logo.jpg';

const $app = document.getElementById('app');

const strInput = 'Hello World';
const srtHolder = 'The result will be here...';
const strHtml = `
<img src="${logo}" alt="logo" />  
<h1>${strInput}</h1>  
<button id="do">Show the reverse of "${strInput}"</button>
<button id="reset">Do reset</button>
<p id="result">${srtHolder}</p>
`;

$app.innerHTML = strHtml;

const $result = document.getElementById('result');

document.getElementById('do').onclick = () => {
  $result.innerHTML = `The reverse of "${strInput}" is "${strReverse(strInput)}"`;
};
document.getElementById('reset').onclick = () => {
  $result.innerHTML = srtHolder;
};uti

新建src/util/index.js

export function strReverse(str) {
  return str.split('').reverse().join('');
}

index.html(去掉引用,webpack会自动加入)

<!DOCTYPE html>
<html lang="zh">
<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>Hello World</title>
</head>
<body>
  <div id="app"></div>
</body>
</html>

3、配置webpack、babel、postcss

webpack默认的配置文件是webpack.config.js。但是通常的,我们会在开发环境引用webpack.dev.js,生产环境用webpack.prod.js,所以我们一步到位,建立config目录,直接写webpack.prod.js,webpack.dev.js并且用webpack-merge提取出它们的公共部分webpack.base.js,方便管理。这里我们把jsx的坑先给填了,反正不影响。

config/webpack.base.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const root = path.resolve(__dirname, '../');

module.exports = {
  entry: path.resolve(root, 'src'),
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: 'babel-loader',
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
        },
      },
      {
        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
        },
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
        },
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: 'Hello World',
      template: './index.html',
    }),
  ],
  resolve: {
    extensions: ['.js', '.jsx', '.json'],
    alias: {
      'src': path.resolve(root, 'src'),
      'util': path.resolve(root, 'src/util'),
    },
  },
};

config/webpack.dev.js

const path = require('path');
const webpack = require('webpack');
const webpackMerge = require('webpack-merge');
const baseConfig = require('./webpack.base');

const root = path.resolve(__dirname, '../');

module.exports = webpackMerge(baseConfig, {
  output: {
    path: path.resolve(root, 'dist'),
    filename: 'bundle.js',
  },
  module: {
    rules: [
      {
        test: /\.(css|less)$/,
        include: path.resolve(root, 'src'),
        use: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader'],
      },
    ],
  },
  devtool: 'cheap-module-eval-source-map',
  devServer: {
    contentBase: path.resolve(root, 'dist'),
    port: 9000,
    hot: true,
  },
  plugins: [
    new webpack.NamedModulesPlugin(),
    new webpack.HotModuleReplacementPlugin(),
  ],
});

config/webpack.prod.js

const path = require('path');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const webpackMerge = require('webpack-merge');
const baseConfig = require('./webpack.base');

const root = path.resolve(__dirname, '../');

module.exports = webpackMerge(baseConfig, {
  output: {
    path: path.resolve(root, 'dist'),
    filename: 'bundle.[chunkhash:10].js',
  },
  module: {
    rules: [
      {
        test: /\.(css|less)$/,
        include: path.resolve(root, 'src'),
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: [{
            loader: 'css-loader',
            options: {
              minimize: true,
            },
          }, 'postcss-loader', 'less-loader'],
        }),
      },
    ],
  },
  devtool: '#source-map',
  plugins: [
    new UglifyJsPlugin({
      uglifyOptions: {
        compress: {
          warnings: false,
        },
      },
      sourceMap: true,
      parallel: true,
    }),
    new ExtractTextPlugin({
      filename: 'bundle.[contenthash:10].css',
      allChunks: true,
    }),
  ],
});

.babelrc

{
  "presets": [
    ["env",{ "modules": false }],
    "stage-2"
  ]
}

.postcssrc.js

module.exports = {
  "plugins": {
    "postcss-import": {},
    "postcss-url": {},
    "autoprefixer": {}
  }
}

然后,在package.json里的scripts里加上prod和dev,分别对应生产和开发环境

"scripts": {
  "prod": "webpack --config config/webpack.prod.js",
  "dev": "webpack-dev-server --config config/webpack.dev.js --open"
},

4、试运行

先试试生产环境的命令,在命令行里输入

$ npm run prod

可以看到,生成了一个dist文件夹,这个就是我们以后会放到生产环境的文件夹。但是!!我们之前已经把它gitignore了。这样做的目的是为了不污染线上的环境,每次上线都是在线上打包,不会出现开发时的各种开发到一半的文件。

从今以后,我们想要看效果,就要点开dist/index.html文件来看了。打开试试吧。

再试试开发环境的命令

$ npm run dev

浏览器打开localhost:9000或127.0.0.1:9000。随便改一改js或css试试,是不是自动刷新了。这在我们开发时会比较有好一些,现在整体的环境已经有一个完整的雏形了。别忘了提交git,记录一下

$ git add .
$ git commit -m 'webpack init'

5、配置展示

全部变化可看笔者的github记录,还是很清晰的。

package.json

{
  "name": "demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "prod": "webpack --config config/webpack.prod.js",
    "dev": "webpack-dev-server --config config/webpack.dev.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.4",
    "babel-preset-env": "^1.6.1",
    "babel-preset-stage-2": "^6.24.1",
    "css-loader": "^0.28.11",
    "extract-text-webpack-plugin": "^3.0.2",
    "file-loader": "^1.1.11",
    "html-webpack-plugin": "^3.1.0",
    "postcss-import": "^11.1.0",
    "postcss-loader": "^2.1.3",
    "postcss-url": "^7.3.1",
    "style-loader": "^0.20.3",
    "url-loader": "^1.0.1",
    "webpack": "^3.11.0",
    "webpack-dev-server": "^2.11.2",
    "webpack-merge": "^4.1.2"
  }
}

项目结构

demo
  |- config
    |- webpack.base.js
    |- webpack.dev.js
    |- webpack.prod.js
  |- src/
    |- assets/
     |- logo.jpg
    |- index.css
    |- index.js
  |- .babelrc
  |- .gitignore
  |- .postcssrc.js
  |- index.html
  |- package.json


猜你喜欢

转载自blog.csdn.net/zhaolandelong/article/details/79658026