lovelmh13/myBlog

小程序使用webpack编译scss成wxss

lovelmh13 opened this issue · 2 comments

首先说明,webpack.config.js 的代码来自于 【webpack】【小程序】小程序使用sass,使用webpack单独处理sass到wxss

把每个页面文件夹里面的scss/css文件编译成wxss供小程序使用其他文件不做处理:
使用工具先获取到所有需要处理的scss/css文件以及路径;
通过scss-loader编译成css;
通过插件将编译后的css文件根据获取的路径输出到相应的文件夹并改后缀为.wxss;

先来看一下整体代码和效果:

image

image

为什么用 webpack 来编译 scss

首先说说一下,为什么用webpack

网上搜了一下,社区里面有官方的人说没必要用scss, 看是原生的wxss写起来的确有那么一丝的不爽。

然后看到之前有人用gulp来编译scss,但是在这个webpack一统天下的时代,未来可能还会需要用到其他的编译的功能,gulp没有webpack来的方便。

思路

通过设置 多入口起点, 来使得每个有scss的目录下,都生成一个对应的wxss

修改一下目录结构

在当前目录下npm init一下,创建一个src目录,把除了project.config.json之外的小程序文件都放进src中。

找到scss文件所在的目录

// CSS入口配置
const CSS_PATH = {
	pattern: [ './src/**/*.scss', './src/**/*.css' ],
	src: path.join(__dirname, 'src')
};

// 遍历所有需要打包的SCSS/CSS文件路径
let getCSSEntries = (config) => {
	let fileList = glob.sync(config.pattern);
	return fileList.reduce((previous, current) => {
		let filePath = path.parse(path.relative(config.src, current));
		let withoutSuffix = path.join(filePath.dir, filePath.name);
		previous[withoutSuffix] = path.resolve(__dirname, current);
		return previous;
	}, {});
};

这里如果打印一下,就会看见我们已经拿到了每个scss文件所在的目录:
image

loader 配置

module: {
	rules: [
		{
			test: /\.(scss|sass|css)$/,
			use: [
				// 需要用到的 loader
				MiniCssExtractPlugin.loader,
				'css-loader',
				'sass-loader'
			]
		}
	]
},

全部的配置

webpack.config.js

// 单独打包样式文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
//删除多余js
const FixStyleOnlyEntriesPlugin = require('webpack-fix-style-only-entries');
const path = require('path');
const glob = require('globby');
// CSS入口配置
const CSS_PATH = {
	pattern: [ './src/**/*.scss', './src/**/*.css' ],
	src: path.join(__dirname, 'src')
};

// 遍历所有需要打包的SCSS/CSS文件路径
let getCSSEntries = (config) => {
	let fileList = glob.sync(config.pattern);
	return fileList.reduce((previous, current) => {
		let filePath = path.parse(path.relative(config.src, current));
		let withoutSuffix = path.join(filePath.dir, filePath.name);
		previous[withoutSuffix] = path.resolve(__dirname, current);
		return previous;
	}, {});
};
console.log('getCSSEntries', getCSSEntries(CSS_PATH))
console.log('__dirname', __dirname)
let config = {
	entry: getCSSEntries(CSS_PATH),
	output: {
		path: __dirname
	},
	module: {
		rules: [
			{
				test: /\.(scss|sass|css)$/,
				use: [
					// 需要用到的 loader
					MiniCssExtractPlugin.loader,
					'css-loader',
					'sass-loader'
				]
			}
		]
	},
	plugins: [
		new FixStyleOnlyEntriesPlugin(),
		new MiniCssExtractPlugin({
			filename: '/src/[name].wxss'
		})
	],
	resolve: {
		extensions: [ '.scss' ]
	}
};

module.exports = config;

package.json

可以使用 cross-env , 或者直接写webpack --webpack.config.js

"scripts": {
    "dev": "cross-env NODE_ENV=development webpack --webpack.config.js",
    "build": "cross-env NODE_ENV=production webpack --config webpack.config.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },

修改 project.config.json 编译入口

{
	"description": "项目配置文件",
	"miniprogramRoot": "src/",
        ...
}

运行npm run dev

为了方便,可以在小程序开发工具 -> 详情 -> 本地设置 -> 启用自定义处理命令 写上 npm run dev

首先说明,webpack.config.js 的代码来自于 【webpack】【小程序】小程序使用sass,使用webpack单独处理sass到wxss

把每个页面文件夹里面的scss/css文件编译成wxss供小程序使用其他文件不做处理:
使用工具先获取到所有需要处理的scss/css文件以及路径;
通过scss-loader编译成css;
通过插件将编译后的css文件根据获取的路径输出到相应的文件夹并改后缀为.wxss;

先来看一下整体代码和效果:

image

image

为什么用 webpack 来编译 scss

首先说说一下,为什么用webpack

网上搜了一下,社区里面有官方的人说没必要用scss, 看是原生的wxss写起来的确有那么一丝的不爽。

然后看到之前有人用gulp来编译scss,但是在这个webpack一统天下的时代,未来可能还会需要用到其他的编译的功能,gulp没有webpack来的方便。

思路

通过设置 多入口起点, 来使得每个有scss的目录下,都生成一个对应的wxss

修改一下目录结构

在当前目录下npm init一下,创建一个src目录,把除了project.config.json之外的小程序文件都放进src中。

找到scss文件所在的目录

// CSS入口配置
const CSS_PATH = {
	pattern: [ './src/**/*.scss', './src/**/*.css' ],
	src: path.join(__dirname, 'src')
};

// 遍历所有需要打包的SCSS/CSS文件路径
let getCSSEntries = (config) => {
	let fileList = glob.sync(config.pattern);
	return fileList.reduce((previous, current) => {
		let filePath = path.parse(path.relative(config.src, current));
		let withoutSuffix = path.join(filePath.dir, filePath.name);
		previous[withoutSuffix] = path.resolve(__dirname, current);
		return previous;
	}, {});
};

这里如果打印一下,就会看见我们已经拿到了每个scss文件所在的目录:
image

loader 配置

module: {
	rules: [
		{
			test: /\.(scss|sass|css)$/,
			use: [
				// 需要用到的 loader
				MiniCssExtractPlugin.loader,
				'css-loader',
				'sass-loader'
			]
		}
	]
},

全部的配置

webpack.config.js

// 单独打包样式文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
//删除多余js
const FixStyleOnlyEntriesPlugin = require('webpack-fix-style-only-entries');
const path = require('path');
const glob = require('globby');
// CSS入口配置
const CSS_PATH = {
	pattern: [ './src/**/*.scss', './src/**/*.css' ],
	src: path.join(__dirname, 'src')
};

// 遍历所有需要打包的SCSS/CSS文件路径
let getCSSEntries = (config) => {
	let fileList = glob.sync(config.pattern);
	return fileList.reduce((previous, current) => {
		let filePath = path.parse(path.relative(config.src, current));
		let withoutSuffix = path.join(filePath.dir, filePath.name);
		previous[withoutSuffix] = path.resolve(__dirname, current);
		return previous;
	}, {});
};
console.log('getCSSEntries', getCSSEntries(CSS_PATH))
console.log('__dirname', __dirname)
let config = {
	entry: getCSSEntries(CSS_PATH),
	output: {
		path: __dirname
	},
	module: {
		rules: [
			{
				test: /\.(scss|sass|css)$/,
				use: [
					// 需要用到的 loader
					MiniCssExtractPlugin.loader,
					'css-loader',
					'sass-loader'
				]
			}
		]
	},
	plugins: [
		new FixStyleOnlyEntriesPlugin(),
		new MiniCssExtractPlugin({
			filename: '/src/[name].wxss'
		})
	],
	resolve: {
		extensions: [ '.scss' ]
	}
};

module.exports = config;

package.json

可以使用 cross-env , 或者直接写webpack --webpack.config.js

"scripts": {
    "dev": "cross-env NODE_ENV=development webpack --webpack.config.js",
    "build": "cross-env NODE_ENV=production webpack --config webpack.config.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },

修改 project.config.json 编译入口

{
	"description": "项目配置文件",
	"miniprogramRoot": "src/",
        ...
}

运行npm run dev

为了方便,可以在小程序开发工具 -> 详情 -> 本地设置 -> 启用自定义处理命令 写上 npm run dev

这个方法对于要使用npm包不是很友好,所以,我又改了一下,让它方便npm的使用。

修改project.config.json 编译入口

删掉

{
	"description": "项目配置文件",
        ...
}

前两步,说白了就是还原我们小程序一开始的配置和结构

调整目录结构

首先,我们调整一下之前的目录结构,删掉src,把src里面的东西拿出来,就跟微信小程序一开始给我们生成的目录结构一样。

编写config文件

// webpack.config.js
// 单独打包样式文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
//删除多余js
const FixStyleOnlyEntriesPlugin = require('webpack-fix-style-only-entries');
const path = require('path');
const glob = require('globby');
// CSS入口配置
const CSS_PATH = {
	pattern: [ './pages/**/*.scss', './pages/**/*.css',  './style/**/*.scss', './style/**/*.css', './utils/**/*.scss', './utils/**/*.css' ],
	src: path.join(__dirname, './')
};

// 遍历所有需要打包的SCSS/CSS文件路径
let getCSSEntries = (config) => {
	let fileList = glob.sync(config.pattern);
	return fileList.reduce((previous, current) => {
		let filePath = path.parse(path.relative(config.src, current));
		let withoutSuffix = path.join(filePath.dir, filePath.name);
		previous[withoutSuffix] = path.resolve(__dirname, current);
		return previous;
	}, {});
};
console.log('getCSSEntries', getCSSEntries(CSS_PATH))
console.log('__dirname', __dirname)
let config = {
	entry: getCSSEntries(CSS_PATH),
	output: {
		path: __dirname
	},
	module: {
		rules: [
			{
				test: /\.(scss|sass|css)$/,
				exclude: /node_modules/, // 排除掉node_modules,不过不加现在貌似也不会编译node_modules
				use: [
					// 需要用到的 loader
					MiniCssExtractPlugin.loader,
					'css-loader',
					'sass-loader'
				]
			}
		]
	},
	plugins: [
		new FixStyleOnlyEntriesPlugin(),
		new MiniCssExtractPlugin({
			filename: '/[name].wxss'
		})
	],
	resolve: {
		extensions: [ '.scss' ]
	}
};

module.exports = config;

新思路:
像 taro 一样,在小程序之外去 build 代码,小程序去引用编译后的 dist 目录。就不用去在小程序开发工具里去设置预处理等命令了