Я работал над файлом SCSS, который использует Tailwind, и все компилировалось нормально, пока я не скопировал в правило, подобное
.selector {
@apply .md:mb-6;
}
, и не получил ошибку:
CssSyntaxError: /server/app/layout/_footer.scss:6:4: @apply
нельзя использовать с .md: mb-6, поскольку .md: mb-6 вложено в правило at (@media).
забывая, что это должно быть
.selector {
@screen md {
@apply .mb-6;
}
}
, которое я использовал раньше в других проектах без проблем.
Поэтому я обновил файл SCSS с помощью @screen
правило, но есть та же проблема.
Итак, я полностью удалил правило, но все равно получил ту же ошибку.
Затем я попытался удалить все в файле;получил ту же ошибку.
Затем я удалил _footer.scss
из мастер-файла, в который он был импортирован;Я получил ту же ошибку.
Я даже попытался удалить файл.
Ошибка продолжает указывать на тот же файл и номер строки, даже если он больше не должен существовать в проекте.
Путь в ошибке также неверен, потому что он должен быть /server/app/src/scss/layout/
, а не /server/app/layout/
.
Кто-нибудь есть какие-либо идеи, что происходит?
РЕДАКТИРОВАТЬ: С тех пор я заменил папку node_modules
, pacakge.json
и файл gulp файлом из другого проекта, и теперь CSS компилируется нормально, поэтому кажется, что с настройкой что-то не так, хотя я не могу понять, почемувсе работало нормально со старой настройкой (которая начиналась с https://github.com/nystudio107/craft) до тех пор, пока не возникла ошибка, а затем ничего не делала, пока я ее не заменил.
Но вот старая настройка дляради полноты.
package.json
{
"paths": {
"src": {
"base": "./src/",
"css": "",
"img": "./src/img/",
"js": "./src/js/",
"scss": "./src/scss/"
},
"dist": {
"base": "./public_html/",
"css": "./public_html/assets/css/",
"js": "./public_html/assets/js/",
"fonts": "./public_html/assets/fonts/",
"img": "./public_html/assets/img/"
},
"build": {
"base": "./build/",
"css": "./build/css/",
"js": "./build/js/",
"html": "./build/html/",
"img": "./build/img/"
},
"tailwindcss": {
"src": "./build/css/master.css",
"conf": "./tailwind.js"
},
"scss": [
{
"src": "./src/scss/master.scss"
}
],
"templates": "./public_html/site/templates/"
},
"urls": {
"live": "https://example.com.au/",
"local": "http://example.local/",
"critical": "https://example.com.au/"
},
"vars": {
"siteCssName": "site.combined.min.css",
"scssName": "master.scss",
"cssName": "master.css"
},
"globs": {
"distCss": [
"./node_modules/normalize.css/normalize.css",
"./build/css/*.css"
],
"img": [
"./public_html/assets/img/"
],
"components": [],
"critical": [],
"download": [
{
"url": "https://www.google-analytics.com/analytics.js",
"dest": "./public_html/assets/js/"
}
],
"distJs": [
"./build/js/*.js",
"./node_modules/lazysizes/lazysizes.min.js",
"./node_modules/lazysizes/plugins/bgset/ls.bgset.min.js",
"./node_modules/picturefill/dist/picturefill.min.js"
],
"prismJs": [],
"babelJs": [
"./src/js/*.js"
],
"inlineJs": [
"./node_modules/fg-loadcss/src/loadCSS.js",
"./node_modules/fg-loadcss/src/cssrelpreload.js",
"./node_modules/fontfaceobserver/fontfaceobserver.js",
"./node_modules/loadjs/dist/loadjs.min.js"
]
},
"dependencies": {
"fg-loadcss": "^1.2.0",
"fontfaceobserver": "^2.0.5",
"lazysizes": "^2.0.6",
"loadjs": "^3.6.1",
"normalize.css": "^5.0.0",
"picturefill": "^3.0.2"
},
"devDependencies": {
"babel-plugin-transform-runtime": "^6.15.0",
"babel-preset-es2015": "^6.16.0",
"chalk": "^1.1.3",
"critical": "^1.1.0",
"fancy-log": "^1.3.3",
"git-rev-sync": "^1.7.1",
"gulp": "^3.9.0",
"gulp-autoprefixer": "^3.1.0",
"gulp-babel": "^6.1.2",
"gulp-cached": "^1.1.1",
"gulp-concat": "^2.6.0",
"gulp-cssnano": "^2.1.2",
"gulp-debug": "^2.1.2",
"gulp-download": "^0.0.1",
"gulp-favicons": "^2.2.6",
"gulp-filter": "^5.0.1",
"gulp-header": "^1.8.7",
"gulp-if": "^2.0.1",
"gulp-imagemin": "^3.1.1",
"gulp-livereload": "^3.8.1",
"gulp-load-plugins": "^1.3.0",
"gulp-newer": "^1.2.0",
"gulp-plumber": "^1.1.0",
"gulp-postcss": "^7.0.0",
"gulp-print": "^2.0.1",
"gulp-purgecss": "^0.15.0",
"gulp-rename": "^1.2.2",
"gulp-replace": "0.5.4",
"gulp-rev": "^7.1.0",
"gulp-sass": "^3.2.0",
"gulp-size": "^2.1.0",
"gulp-sourcemaps": "^2.2.1",
"gulp-streamify": "1.0.2",
"gulp-uglify": "^1.5.4",
"moment": "^2.14.1",
"pa11y": "^4.11.0",
"tailwindcss": "^0.7.4",
"tailwindcss-visuallyhidden": "^1.0.2",
"vinyl-source-stream": "^1.1.0"
},
"scripts": {
"start": "gulp",
"build": "gulp build"
}
}
gulpfile.js
// jshint esversion: 6
// jshint node: true
"use strict";
// package vars
const pkg = require("./package.json");
// gulp
const gulp = require("gulp");
// load all plugins in "devDependencies" into the variable $
const $ = require("gulp-load-plugins")({
pattern: ["*"],
scope: ["devDependencies"]
});
// error logging
const onError = (err) => {
console.log(err);
};
// Our banner
const banner = (function() {
let result = "";
try {
result = [
"/**",
" * @project <%= pkg.name %>",
" * @author <%= pkg.author %>",
" * @build " + $.moment().format("llll") + " ET",
" * @release " + $.gitRevSync.long() + " [" + $.gitRevSync.branch() + "]",
" * @copyright Copyright (c) " + $.moment().format("YYYY") + ", <%= pkg.copyright %>",
" *",
" */",
""
].join("\n");
}
catch (err) {
}
return result;
})();
// scss - build the scss to the build folder, including the required paths, and writing out a sourcemap
gulp.task("scss", () => {
$.fancyLog("-> Compiling scss");
return gulp.src(pkg.paths.src.scss + pkg.vars.scssName)
.pipe($.plumber({errorHandler: onError}))
.pipe($.sourcemaps.init({loadMaps: true}))
.pipe($.sass({
includePaths: pkg.paths.scss
})
.on("error", $.sass.logError))
.pipe($.cached("sass_compile"))
.pipe($.autoprefixer())
.pipe($.sourcemaps.write("./"))
.pipe($.size({gzip: true, showFiles: true}))
.pipe(gulp.dest(pkg.paths.build.css));
});
// tailwind task - build the Tailwind CSS
gulp.task("tailwind", () => {
$.fancyLog("-> Compiling tailwind css");
return gulp.src(pkg.paths.tailwindcss.src)
.pipe($.postcss([
$.tailwindcss(pkg.paths.tailwindcss.conf),
require("autoprefixer"),
]))
.pipe($.if(process.env.NODE_ENV === "production",
$.purgecss({
extractors: [{
extractor: TailwindExtractor,
extensions: ["html", "php", "inc", "twig", "css", "js"]
}],
whitelist: pkg.globs.purgecssWhitelist,
content: pkg.globs.purgecss
})
))
.pipe(gulp.dest(pkg.paths.build.css));
});
// Custom PurgeCSS extractor for Tailwind that allows special characters in
// class names.
//
// https://github.com/FullHuman/purgecss#extractor
class TailwindExtractor {
static extract(content) {
return content.match(/[A-z0-9-:\/]+/g);
}
}
// css task - combine & minimize any distribution CSS into the public css folder, and add our banner to it
gulp.task("css", ["tailwind", "scss"], () => {
$.fancyLog("-> Building css");
return gulp.src(pkg.globs.distCss)
.pipe($.plumber({errorHandler: onError}))
.pipe($.newer({dest: pkg.paths.dist.css + pkg.vars.siteCssName}))
.pipe($.print())
.pipe($.sourcemaps.init({loadMaps: true}))
.pipe($.concat(pkg.vars.siteCssName))
.pipe($.if(process.env.NODE_ENV === "production",
$.cssnano({
discardComments: {
removeAll: true
},
discardDuplicates: true,
discardEmpty: true,
minifyFontValues: true,
minifySelectors: true
})
))
.pipe($.header(banner, {pkg: pkg}))
.pipe($.sourcemaps.write("./"))
.pipe($.size({gzip: true, showFiles: true}))
.pipe(gulp.dest(pkg.paths.dist.css))
.pipe($.filter("**/*.css"))
.pipe($.livereload());
});
// js task - minimize any distribution Javascript into the public js folder, and add our banner to it
gulp.task("js-app", () => {
$.fancyLog("-> Building js-app");
if (process.env.NODE_ENV === "production") {
const browserifyMethod = $.browserify;
} else {
const browserifyMethod = $.browserifyIncremental;
}
const bundleStream = browserifyMethod(pkg.paths.src.jsApp, {
paths: pkg.globs.jsIncludes,
cacheFile: pkg.paths.build.base + "browserify-cache.json"
})
.transform($.babelify, {presets: ["es2015"]})
.transform($.vueify)
.bundle();
return bundleStream
.pipe($.plumber({errorHandler: onError}))
.pipe($.vinylSourceStream("app.js"))
.pipe($.if(process.env.NODE_ENV === "production",
$.streamify($.uglify())
))
.pipe($.streamify($.header(banner, {pkg: pkg})))
.pipe($.streamify($.size({gzip: true, showFiles: true})))
.pipe(gulp.dest(pkg.paths.dist.js));
});
// babel js task - transpile our Javascript into the build directory
gulp.task("js-babel", () => {
$.fancyLog("-> Transpiling Javascript via Babel…");
return gulp.src(pkg.globs.babelJs)
.pipe($.plumber({errorHandler: onError}))
.pipe($.newer({dest: pkg.paths.build.js}))
.pipe($.babel())
.pipe($.size({gzip: true, showFiles: true}))
.pipe(gulp.dest(pkg.paths.build.js));
});
// inline js task - minimize the inline Javascript into _inlinejs in the templates path
gulp.task("js-inline", ["js-babel"], () => {
$.fancyLog("-> Copying inline js");
return gulp.src(pkg.globs.inlineJs)
.pipe($.plumber({errorHandler: onError}))
.pipe($.if(["*.js", "!*.min.js"],
$.newer({dest: pkg.paths.templates + "_inlinejs", ext: ".min.js"}),
$.newer({dest: pkg.paths.templates + "_inlinejs"})
))
.pipe($.if(["*.js", "!*.min.js"],
$.uglify()
))
.pipe($.if(["*.js", "!*.min.js"],
$.rename({suffix: ".min"})
))
.pipe($.size({gzip: true, showFiles: true}))
.pipe(gulp.dest(pkg.paths.templates + "_inlinejs"))
.pipe($.filter("**/*.js"))
.pipe($.livereload());
});
// js task - minimize any distribution Javascript into the public js folder, and add our banner to it
gulp.task("js", ["js-inline"], () => {
$.fancyLog("-> Building js");
return gulp.src(pkg.globs.distJs)
.pipe($.plumber({errorHandler: onError}))
.pipe($.if(["*.js", "!*.min.js"],
$.newer({dest: pkg.paths.dist.js, ext: ".min.js"}),
$.newer({dest: pkg.paths.dist.js})
))
.pipe($.if(["*.js", "!*.min.js"],
$.uglify()
))
.pipe($.if(["*.js", "!*.min.js"],
$.rename({suffix: ".min"})
))
.pipe($.header(banner, {pkg: pkg}))
.pipe($.size({gzip: true, showFiles: true}))
.pipe(gulp.dest(pkg.paths.dist.js))
.pipe($.filter("**/*.js"))
.pipe($.livereload());
});
// Process data in an array synchronously, moving onto the n+1 item only after the nth item callback
function doSynchronousLoop(data, processData, done) {
if (data.length > 0) {
const loop = (data, i, processData, done) => {
processData(data[i], i, () => {
if (++i < data.length) {
loop(data, i, processData, done);
} else {
done();
}
});
};
loop(data, 0, processData, done);
} else {
done();
}
}
// Process the downloads one at a time
function processDownload(element, i, callback) {
const downloadSrc = element.url;
const downloadDest = element.dest;
$.fancyLog("-> Downloading URL: " + $.chalk.cyan(downloadSrc) + " -> " + $.chalk.magenta(downloadDest));
$.download(downloadSrc)
.pipe(gulp.dest(downloadDest));
callback();
}
// download task
gulp.task("download", (callback) => {
doSynchronousLoop(pkg.globs.download, processDownload, () => {
// all done
callback();
});
});
// Run pa11y accessibility tests on each template
function processAccessibility(element, i, callback) {
const accessibilitySrc = pkg.urls.critical + element.url;
const cliReporter = require("./node_modules/pa11y/reporter/cli.js");
const options = {
log: cliReporter,
ignore:
[
"notice",
"warning"
],
};
const test = $.pa11y(options);
$.fancyLog("-> Checking Accessibility for URL: " + $.chalk.cyan(accessibilitySrc));
test.run(accessibilitySrc, (error, results) => {
cliReporter.results(results, accessibilitySrc);
callback();
});
}
// accessibility task
gulp.task("a11y", (callback) => {
doSynchronousLoop(pkg.globs.critical, processAccessibility, () => {
// all done
callback();
});
});
// imagemin task
gulp.task("imagemin", () => {
$.fancyLog("-> Minimizing images in " + pkg.paths.src.img);
return gulp.src(pkg.paths.src.img + "**/*.{png,jpg,jpeg,gif,svg}")
.pipe($.imagemin({
progressive: true,
interlaced: true,
optimizationLevel: 7,
svgoPlugins: [{removeViewBox: false}],
verbose: true,
use: []
}))
.pipe(gulp.dest(pkg.paths.dist.img));
});
// static assets version task
gulp.task("static-assets-version", () => {
gulp.src(pkg.paths.craftConfig + "general.php")
.pipe($.replace(/'staticAssetsVersion' => (\d+),/g, function(match, p1, offset, string) {
p1++;
$.fancyLog("-> Changed staticAssetsVersion to " + p1);
return "'staticAssetsVersion' => " + p1 + ",";
}))
.pipe(gulp.dest(pkg.paths.craftConfig));
});
// set the node environment to development
gulp.task("set-dev-node-env", function() {
$.fancyLog("-> Setting NODE_ENV to development");
return process.env.NODE_ENV = "development";
});
// set the node environment to production
gulp.task("set-prod-node-env", function() {
$.fancyLog("-> Setting NODE_ENV to production");
return process.env.NODE_ENV = "production";
});
// Default task
gulp.task("default", ["set-dev-node-env","css", "js"], () => {
$.fancyLog("-> Livereload listening for changes");
$.livereload.listen();
gulp.watch([pkg.paths.src.scss + "**/*.scss"], ["css"]);
gulp.watch([pkg.paths.src.css + "**/*.css"], ["css"]);
gulp.watch([pkg.paths.src.js + "**/*.js"], ["js"]);
gulp.watch([pkg.paths.templates + "**/*.{html,htm,twig,php,inc}"], () => {
gulp.src(pkg.paths.templates)
.pipe($.plumber({errorHandler: onError}))
.pipe($.livereload());
});
});
// Production build
gulp.task("build", ["set-prod-node-env", "static-assets-version", "download", "imagemin"]);